From 61185899990c4dd8f9db3c5e0f765604d81f45bb Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Feb 2020 23:05:57 +0900 Subject: [PATCH 001/139] initial commit --- .circleci/config.yml | 40 + .gitignore | 119 + LICENSE | 21 + README.md | 37 + ZString.sln | 56 + sandbox/ConsoleApp/ConsoleApp.csproj | 12 + sandbox/ConsoleApp/Program.cs | 47 + src/ZString/FormatParser.cs | 55 + .../Utf16ValueStringBuilder.AppendFormat.cs | 2848 +++++++++++++++++ .../Utf16ValueStringBuilder.AppendFormat.tt | 115 + .../Utf16ValueStringBuilder.AppendMany.cs | 1538 +++++++++ .../Utf16ValueStringBuilder.AppendMany.tt | 57 + ...Utf16ValueStringBuilder.CreateFormatter.cs | 73 + ...Utf16ValueStringBuilder.CreateFormatter.tt | 46 + ...alueStringBuilder.SpanFormattableAppend.cs | 429 +++ ...alueStringBuilder.SpanFormattableAppend.tt | 66 + src/ZString/Utf16ValueStringBuilder.cs | 226 ++ .../Utf8ValueStringBuilder.AppendFormat.cs | 2800 ++++++++++++++++ .../Utf8ValueStringBuilder.AppendFormat.tt | 112 + .../Utf8/Utf8ValueStringBuilder.AppendMany.cs | 1538 +++++++++ .../Utf8/Utf8ValueStringBuilder.AppendMany.tt | 57 + .../Utf8ValueStringBuilder.CreateFormatter.cs | 75 + .../Utf8ValueStringBuilder.CreateFormatter.tt | 48 + ...alueStringBuilder.SpanFormattableAppend.cs | 431 +++ ...alueStringBuilder.SpanFormattableAppend.tt | 68 + src/ZString/Utf8ValueStringBuilder.cs | 242 ++ src/ZString/ZString.Format.cs | 234 ++ src/ZString/ZString.Format.tt | 49 + src/ZString/ZString.cs | 19 + src/ZString/ZString.csproj | 115 + tests/ZString.Tests/FormatTest.cs | 23 + tests/ZString.Tests/ZString.Tests.csproj | 29 + 32 files changed, 11625 insertions(+) create mode 100644 .circleci/config.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 ZString.sln create mode 100644 sandbox/ConsoleApp/ConsoleApp.csproj create mode 100644 sandbox/ConsoleApp/Program.cs create mode 100644 src/ZString/FormatParser.cs create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt create mode 100644 src/ZString/Utf16ValueStringBuilder.cs create mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs create mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt create mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs create mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt create mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs create mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt create mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs create mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt create mode 100644 src/ZString/Utf8ValueStringBuilder.cs create mode 100644 src/ZString/ZString.Format.cs create mode 100644 src/ZString/ZString.Format.tt create mode 100644 src/ZString/ZString.cs create mode 100644 src/ZString/ZString.csproj create mode 100644 tests/ZString.Tests/FormatTest.cs create mode 100644 tests/ZString.Tests/ZString.Tests.csproj diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..db79ede6 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,40 @@ +version: 2.1 +executors: + dotnet: + docker: + - image: mcr.microsoft.com/dotnet/core/sdk:3.1 + environment: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + NUGET_XMLDOC_MODE: skip +jobs: + build-test: + executor: dotnet + steps: + - checkout + - run: dotnet build -c Debug + - run: dotnet test -c Debug --no-build < /dev/null + build-push: + executor: dotnet + steps: + - checkout + - run: dotnet build -c Release -p:Version=${CIRCLE_TAG} + - run: dotnet test -c Release --no-build < /dev/null + - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${CIRCLE_TAG} + - store_artifacts: + path: src/ZString/bin/Release/ + destination: /ZString/ + - run: dotnet nuget push ./src/ZString/bin/Release/ZString.${CIRCLE_TAG}.nupkg -s https://www.nuget.org/api/v2/package -k ${NUGET_KEY} +workflows: + version: 2 + build-and-push: + jobs: + - build-test: + filters: + tags: + only: /.*/ + - build-push: + filters: + tags: + only: /^\d\.\d\.\d.*/ + branches: + ignore: /.*/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f79f9627 --- /dev/null +++ b/.gitignore @@ -0,0 +1,119 @@ +# Build Folders (you can keep bin if you'd like, to store dlls and pdbs) +[Bb]in/ +[Oo]bj/ + +# mstest test results +TestResults + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +*_i.c +*_p.c +*.ilk +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.log +*.vspscc +*.vssscc +.builds + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper* + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Publish Web Output +*.Publish.xml + +# NuGet Packages Directory +packages + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +[Bb]in +[Oo]bj +sql +TestResults +[Tt]est[Rr]esult* +*.Cache +ClientBin +[Ss]tyle[Cc]op.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +.vs/config/applicationhost.config +.vs/restore.dg + +# OTHER +nuget/tools/* +*.nupkg + +.vs + +# Unity +Library/ +Temp/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..e847bcde --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Cysharp, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..fe9bc9eb --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +ZString +=== +[![CircleCI](https://circleci.com/gh/Cysharp/ZString.svg?style=svg)](https://circleci.com/gh/Cysharp/ZString) + +WIP + +**Z**ero alloction **String**Builder for .NET Core and Unity. + +```csharp +using var sb = ZString.CreateStringBuilder(); + +sb.AppendLine("foo"); +sb.AppendLine(42); +sb.AppendLine("bar"); +sb.AppendLine(123.456); + +Console.WriteLine(sb.ToString()); + +// format, shortform +var str = ZString.Format("foo {0} bar {1}", 42, 123.456); +``` + +```csharp +// write to Utf8 directly +using var sb = ZString.CreateUtf8StringBuilder(); + +sb.AppendLine("foo"); +sb.AppendLine(42); +sb.AppendLine("bar"); +sb.AppendLine(123.456); + +await sb.CopyToAsync(stream); +``` + +License +--- +This library is under the MIT License. diff --git a/ZString.sln b/ZString.sln new file mode 100644 index 00000000..e1cf5aac --- /dev/null +++ b/ZString.sln @@ -0,0 +1,56 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29613.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{175A1317-7622-4CC3-9553-1E9E908FF085}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + .circleci\config.yml = .circleci\config.yml + LICENSE = LICENSE + README.md = README.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B385367D-2EB5-49B3-A3EF-922151EC1904}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sandbox", "sandbox", "{A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0803618F-C4E8-4D37-831E-5D26C5574F49}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZString", "src\ZString\ZString.csproj", "{7B09D422-D19A-457E-ADA0-4CDC2DC581BB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "sandbox\ConsoleApp\ConsoleApp.csproj", "{9ADF67E1-1872-43D3-882E-607071726FE7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZString.Tests", "tests\ZString.Tests\ZString.Tests.csproj", "{62090C00-9727-4375-BE40-ABE2F4D41571}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7B09D422-D19A-457E-ADA0-4CDC2DC581BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B09D422-D19A-457E-ADA0-4CDC2DC581BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B09D422-D19A-457E-ADA0-4CDC2DC581BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B09D422-D19A-457E-ADA0-4CDC2DC581BB}.Release|Any CPU.Build.0 = Release|Any CPU + {9ADF67E1-1872-43D3-882E-607071726FE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9ADF67E1-1872-43D3-882E-607071726FE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9ADF67E1-1872-43D3-882E-607071726FE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9ADF67E1-1872-43D3-882E-607071726FE7}.Release|Any CPU.Build.0 = Release|Any CPU + {62090C00-9727-4375-BE40-ABE2F4D41571}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62090C00-9727-4375-BE40-ABE2F4D41571}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62090C00-9727-4375-BE40-ABE2F4D41571}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62090C00-9727-4375-BE40-ABE2F4D41571}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {7B09D422-D19A-457E-ADA0-4CDC2DC581BB} = {B385367D-2EB5-49B3-A3EF-922151EC1904} + {9ADF67E1-1872-43D3-882E-607071726FE7} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} + {62090C00-9727-4375-BE40-ABE2F4D41571} = {0803618F-C4E8-4D37-831E-5D26C5574F49} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DF39BF43-3E0E-4F7D-9943-7E50D301234D} + EndGlobalSection +EndGlobal diff --git a/sandbox/ConsoleApp/ConsoleApp.csproj b/sandbox/ConsoleApp/ConsoleApp.csproj new file mode 100644 index 00000000..42d8a9e0 --- /dev/null +++ b/sandbox/ConsoleApp/ConsoleApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp3.1 + + + + + + + diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs new file mode 100644 index 00000000..bac97ba0 --- /dev/null +++ b/sandbox/ConsoleApp/Program.cs @@ -0,0 +1,47 @@ +using Cysharp.Text; +using System; + +namespace ConsoleApp +{ + class Program + { + static void Main(string[] args) + { + Run(); + } + + static void Run() + { + //using var sb = ZString.CreateStringBuilder(); + + //sb.AppendLine("foo"); + //sb.AppendLine(100); + //sb.AppendLine("baz"); + //sb.AppendLine(123.4); + //sb.AppendLine("foo", 999, "baz", 1000.4); + + //Console.WriteLine(sb.ToString()); + + //using var sb = ZString.CreateStringBuilder(); + + + //sb.Append(100); + //sb.Append(100, "hogehoge"); + //sb.Append(100, "hogehoge".AsSpan()); + + + //sb.AppendMany("hogehoge", 100, 300); + + + + using var sb2 = ZString.CreateUtf8StringBuilder(); + + sb2.Append("あ"); + sb2.Append(1999); + sb2.Append("bar"); + + Console.WriteLine(sb2.ToString()); + + } + } +} diff --git a/src/ZString/FormatParser.cs b/src/ZString/FormatParser.cs new file mode 100644 index 00000000..10d2bdee --- /dev/null +++ b/src/ZString/FormatParser.cs @@ -0,0 +1,55 @@ +using System; + +namespace Cysharp.Text +{ + internal static class FormatParser + { + // {index[,alignment][:formatString]} + + public readonly ref struct ParseResult + { + public readonly int Index; + public readonly ReadOnlySpan FormatString; + public readonly int LastIndex; + + public ParseResult(int index, ReadOnlySpan formatString, int lastIndex) + { + Index = index; + FormatString = formatString; + LastIndex = lastIndex; + } + } + + public static ParseResult Parse(ReadOnlySpan format) + { + int index = -1; + var formatStart = -1; + + // ignore start '{' + for (int i = 1; i < format.Length; i++) + { + if (format[i] == '}') + { + if (index == -1) + { + index = int.Parse(format.Slice(1, i - 1)); + return new ParseResult(index, default, i); + } + else + { + var formatString = format.Slice(formatStart, i - formatStart); + return new ParseResult(index, formatString, i); + } + } + + if (index == -1 && format[i] == ',' || format[i] == ':') + { + index = int.Parse(format.Slice(1, i - 1)); + formatStart = i + 1; + } + } + + throw new FormatException("Invalid format string. format:" + format.ToString()); + } + } +} diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs new file mode 100644 index 00000000..f83c2a57 --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -0,0 +1,2848 @@ +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { + public void AppendFormat(ReadOnlySpan format, T0 arg0) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0) + { + AppendFormat(format, arg0); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1) + { + AppendFormat(format, arg0, arg1); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + { + AppendFormat(format, arg0, arg1, arg2); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + AppendFormat(format, arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + case 14: + { + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + case 14: + { + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } + case 15: + { + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt new file mode 100644 index 00000000..63ae04f8 --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt @@ -0,0 +1,115 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + } + + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + } +#> +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { +<# for(var i = 1; i <= 16; i++) { #> + public void AppendFormat<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { +<# for(var j = 0; j < i; j++) { #> + case <#= j #>: + { + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg<#= j #>)); + } + } + index += written; + goto NEXT_LOOP; + } +<# } #> + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + { + AppendFormat(format, <#= CreateParameterNames(i) #>); + AppendNewLine(); + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs new file mode 100644 index 00000000..be38d681 --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs @@ -0,0 +1,1538 @@ +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { + public void AppendMany(T0 arg0, T1 arg1) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1) + { + AppendMany(arg0, arg1); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2) + { + AppendMany(arg0, arg1, arg2); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + AppendMany(arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + AppendMany(arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt new file mode 100644 index 00000000..f100c7f9 --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt @@ -0,0 +1,57 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + } + + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + } +#> +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { +<# for(var i = 2; i <= 16; i++) { #> + public void AppendMany<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) + { + int written; + +<# for(var j = 0; j < i; j++) { #> + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg<#= j #>)); + } + } + index += written; + +<# } #> + } + + public void AppendManyLine<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) + { + AppendMany(<#= CreateParameterNames(i) #>); + AppendNewLine(); + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs new file mode 100644 index 00000000..7369e90e --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -0,0 +1,73 @@ +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { + static object CreateFormatter(Type type) + { + if (type == typeof(Byte)) + { + return new TryFormat((Byte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(DateTime)) + { + return new TryFormat((DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(DateTimeOffset)) + { + return new TryFormat((DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(Decimal)) + { + return new TryFormat((Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(Double)) + { + return new TryFormat((Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(Guid)) + { + return new TryFormat((Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(Int16)) + { + return new TryFormat((Int16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(Int32)) + { + return new TryFormat((Int32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(Int64)) + { + return new TryFormat((Int64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(SByte)) + { + return new TryFormat((SByte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(Single)) + { + return new TryFormat((Single x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(TimeSpan)) + { + return new TryFormat((TimeSpan x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(UInt16)) + { + return new TryFormat((UInt16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(UInt32)) + { + return new TryFormat((UInt32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(UInt64)) + { + return new TryFormat((UInt64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt new file mode 100644 index 00000000..5e92382f --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt @@ -0,0 +1,46 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + var spanFormattables = new Type[] + { + typeof(Byte), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(Decimal), + typeof(Double), + typeof(Guid), + typeof(Int16), + typeof(Int32), + typeof(Int64), + typeof(SByte), + typeof(Single), + typeof(TimeSpan), + typeof(UInt16), + typeof(UInt32), + typeof(UInt64), + // typeof(Version), + }; +#> +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { + static object CreateFormatter(Type type) + { +<# foreach(var t in spanFormattables) { #> + if (type == typeof(<#= t.Name #>)) + { + return new TryFormat<<#= t.Name #>>((<#= t.Name #> x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } +<# } #> + + return null; + } + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs new file mode 100644 index 00000000..2401c2a8 --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -0,0 +1,429 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Byte value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Byte value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(DateTime value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(DateTime value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(DateTimeOffset value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(DateTimeOffset value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Decimal value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Decimal value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Double value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Double value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int16 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int16 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int32 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int32 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int64 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int64 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(SByte value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(SByte value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Single value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Single value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(TimeSpan value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(TimeSpan value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt16 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt16 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt32 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt32 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt64 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt64 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Guid value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Guid value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt new file mode 100644 index 00000000..8f443e74 --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt @@ -0,0 +1,66 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + var spanFormattables = new Type[] + { + typeof(Byte), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(Decimal), + typeof(Double), + typeof(Int16), + typeof(Int32), + typeof(Int64), + typeof(SByte), + typeof(Single), + typeof(TimeSpan), + typeof(UInt16), + typeof(UInt32), + typeof(UInt64), + typeof(Guid), + // typeof(Version), + }; +#> +using System; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { +<# foreach(var t in spanFormattables) { #> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(<#= t.Name #> value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(<#= t.Name #> value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs new file mode 100644 index 00000000..59a63bbb --- /dev/null +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -0,0 +1,226 @@ +using System; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public ref partial struct Utf16ValueStringBuilder + { + delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); + + const int DefaultBufferSize = 32768; // use 32K default buffer. + + static char newLine1; + static char newLine2; + static bool crlf; + + static Utf16ValueStringBuilder() + { + var newLine = Environment.NewLine.ToCharArray(); + if (newLine.Length == 1) + { + // cr or lf + newLine1 = newLine[0]; + crlf = false; + } + else + { + // crlf(windows) + newLine1 = newLine[0]; + newLine2 = newLine[1]; + crlf = true; + } + } + + [ThreadStatic] + static char[] scratchBuffer; + + char[] buffer; + int index; + + public int Length => index; + public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + + internal void Init() + { + var buf = scratchBuffer; + if (buf == null) + { + buf = scratchBuffer = new char[DefaultBufferSize]; + } + + buffer = buf; + index = 0; + } + + public void Dispose() + { + if (buffer.Length != DefaultBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + buffer = null; + index = 0; + } + + void TryGrow(int sizeHint) + { + if (buffer.Length < index + sizeHint) + { + Grow(sizeHint); + } + } + + void Grow(int sizeHint = 0) + { + var nextSize = buffer.Length * 2; + if (sizeHint != 0) + { + nextSize = Math.Max(nextSize, index + sizeHint); + } + + var newBuffer = ArrayPool.Shared.Rent(nextSize); + + buffer.CopyTo(newBuffer, 0); + if (buffer.Length != DefaultBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + + buffer = newBuffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendNewLine() + { + if (crlf) + { + if (buffer.Length - index < 2) Grow(2); + buffer[index] = newLine1; + buffer[index + 1] = newLine2; + index += 2; + } + else + { + if (buffer.Length - index < 1) Grow(1); + buffer[index] = newLine1; + index += 1; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string value) + { + if (buffer.Length - index < value.Length) + { + Grow(value.Length); + } + + value.CopyTo(0, buffer, index, value.Length); + index += value.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string value) + { + Append(value); + AppendNewLine(); + } + + public void Append(T value) + { + if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + public void AppendLine(T value) + { + Append(value); + AppendNewLine(); + } + + // Output + + public bool TryCopyTo(Span destination, out int charsWritten) + { + if (destination.Length < index) + { + charsWritten = 0; + return false; + } + + charsWritten = index; + buffer.AsSpan(0, index).CopyTo(destination); + return true; + } + + public override string ToString() + { + return new string(buffer, 0, index); + } + + // IBufferWriter like interface. + + public Span GetWritableBuffer(int sizeHint = 0) + { + if ((buffer.Length - index) < sizeHint) + { + Grow(sizeHint); + } + + return buffer.AsSpan(index); + } + + public void Advance(int count) + { + index += count; + } + + void ThrowArgumentException(string paramName) + { + throw new ArgumentException("Can't format argument.", paramName); + } + + void ThrowFormatException() + { + throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); + } + + static class FormatterCache + { + public static TryFormat TryFormatDelegate; + static FormatterCache() + { + var formatter = (TryFormat)CreateFormatter(typeof(T)); + if (formatter == null) + { + formatter = new TryFormat(TryFormatDefault); + } + + TryFormatDelegate = formatter; + } + + static bool TryFormatDefault(T value, Span dest, out int written, ReadOnlySpan format) + { + if (value == null) + { + written = 0; + return true; + } + + var s = value.ToString(); + + // also use this length when result is false. + written = s.Length; + return s.AsSpan().TryCopyTo(dest); + } + } + } +} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs new file mode 100644 index 00000000..ad0677c1 --- /dev/null +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -0,0 +1,2800 @@ +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { + public void AppendFormat(ReadOnlySpan format, T0 arg0) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0) + { + AppendFormat(format, arg0); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1) + { + AppendFormat(format, arg0, arg1); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + { + AppendFormat(format, arg0, arg1, arg2); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + AppendFormat(format, arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + case 14: + { + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + case 14: + { + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } + case 15: + { + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt new file mode 100644 index 00000000..38b5cf91 --- /dev/null +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt @@ -0,0 +1,112 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + } + + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + } +#> +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { +<# for(var i = 1; i <= 16; i++) { #> + public void AppendFormat<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.Slice(i)); + copyFrom = indexParse.LastIndex + 1; + i = indexParse.LastIndex; + switch (indexParse.Index) + { +<# for(var j = 0; j < i; j++) { #> + case <#= j #>: + { + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg<#= j #>)); + } + } + index += written; + goto NEXT_LOOP; + } +<# } #> + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + { + AppendFormat(format, <#= CreateParameterNames(i) #>); + AppendNewLine(); + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs new file mode 100644 index 00000000..ffed9b4e --- /dev/null +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs @@ -0,0 +1,1538 @@ +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { + public void AppendMany(T0 arg0, T1 arg1) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1) + { + AppendMany(arg0, arg1); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2) + { + AppendMany(arg0, arg1, arg2); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + AppendMany(arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + AppendMany(arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt new file mode 100644 index 00000000..779ecaa2 --- /dev/null +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt @@ -0,0 +1,57 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + } + + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + } +#> +using System; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { +<# for(var i = 2; i <= 16; i++) { #> + public void AppendMany<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) + { + int written; + +<# for(var j = 0; j < i; j++) { #> + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg<#= j #>)); + } + } + index += written; + +<# } #> + } + + public void AppendManyLine<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) + { + AppendMany(<#= CreateParameterNames(i) #>); + AppendNewLine(); + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs new file mode 100644 index 00000000..c4e83e77 --- /dev/null +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -0,0 +1,75 @@ +using System; +using System.Buffers; +using System.Buffers.Text; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { + static object CreateFormatter(Type type) + { + if (type == typeof(Byte)) + { + return new TryFormat((Byte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(DateTime)) + { + return new TryFormat((DateTime x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(DateTimeOffset)) + { + return new TryFormat((DateTimeOffset x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(Decimal)) + { + return new TryFormat((Decimal x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(Double)) + { + return new TryFormat((Double x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(Guid)) + { + return new TryFormat((Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(Int16)) + { + return new TryFormat((Int16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(Int32)) + { + return new TryFormat((Int32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(Int64)) + { + return new TryFormat((Int64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(SByte)) + { + return new TryFormat((SByte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(Single)) + { + return new TryFormat((Single x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(TimeSpan)) + { + return new TryFormat((TimeSpan x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(UInt16)) + { + return new TryFormat((UInt16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(UInt32)) + { + return new TryFormat((UInt32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(UInt64)) + { + return new TryFormat((UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt new file mode 100644 index 00000000..81cf6000 --- /dev/null +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt @@ -0,0 +1,48 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + var spanFormattables = new Type[] + { + typeof(Byte), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(Decimal), + typeof(Double), + typeof(Guid), + typeof(Int16), + typeof(Int32), + typeof(Int64), + typeof(SByte), + typeof(Single), + typeof(TimeSpan), + typeof(UInt16), + typeof(UInt32), + typeof(UInt64), + // typeof(Version), + }; +#> +using System; +using System.Buffers; +using System.Buffers.Text; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { + static object CreateFormatter(Type type) + { +<# foreach(var t in spanFormattables) { #> + if (type == typeof(<#= t.Name #>)) + { + return new TryFormat<<#= t.Name #>>((<#= t.Name #> x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } +<# } #> + + return null; + } + } +} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs new file mode 100644 index 00000000..90856b21 --- /dev/null +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -0,0 +1,431 @@ +using System; +using System.Buffers; +using System.Buffers.Text; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Byte value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Byte value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(DateTime value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(DateTime value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(DateTimeOffset value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(DateTimeOffset value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Decimal value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Decimal value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Double value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Double value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int16 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int16 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int32 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int32 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int64 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Int64 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(SByte value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(SByte value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Single value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Single value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(TimeSpan value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(TimeSpan value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt16 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt16 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt32 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt32 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt64 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(UInt64 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Guid value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(Guid value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + } +} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt new file mode 100644 index 00000000..0025b409 --- /dev/null +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt @@ -0,0 +1,68 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + var spanFormattables = new Type[] + { + typeof(Byte), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(Decimal), + typeof(Double), + typeof(Int16), + typeof(Int32), + typeof(Int64), + typeof(SByte), + typeof(Single), + typeof(TimeSpan), + typeof(UInt16), + typeof(UInt32), + typeof(UInt64), + typeof(Guid), + // typeof(Version), + }; +#> +using System; +using System.Buffers; +using System.Buffers.Text; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { +<# foreach(var t in spanFormattables) { #> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(<#= t.Name #> value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(<#= t.Name #> value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs new file mode 100644 index 00000000..7c124c49 --- /dev/null +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -0,0 +1,242 @@ +using System; +using System.Buffers; +using System.IO; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace Cysharp.Text +{ + public ref partial struct Utf8ValueStringBuilder + { + delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); + + const int DefaultBufferSize = 65536; // use 64K default buffer. + static Encoding UTF8NoBom = new UTF8Encoding(false); + + static byte newLine1; + static byte newLine2; + static bool crlf; + + static Utf8ValueStringBuilder() + { + var newLine = UTF8NoBom.GetBytes(Environment.NewLine); + if (newLine.Length == 1) + { + // cr or lf + newLine1 = newLine[0]; + crlf = false; + } + else + { + // crlf(windows) + newLine1 = newLine[0]; + newLine2 = newLine[1]; + crlf = true; + } + } + + [ThreadStatic] + static byte[] scratchBuffer; + + byte[] buffer; + int index; + + public int Length => index; + public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + + internal void Init() + { + var buf = scratchBuffer; + if (buf == null) + { + buf = scratchBuffer = new byte[DefaultBufferSize]; + } + + buffer = buf; + index = 0; + } + + public void Dispose() + { + if (buffer.Length != DefaultBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + buffer = null; + index = 0; + } + + void TryGrow(int sizeHint) + { + if (buffer.Length < index + sizeHint) + { + Grow(sizeHint); + } + } + + void Grow(int sizeHint = 0) + { + var nextSize = buffer.Length * 2; + if (sizeHint != 0) + { + nextSize = Math.Max(nextSize, index + sizeHint); + } + + var newBuffer = ArrayPool.Shared.Rent(nextSize); + + buffer.CopyTo(newBuffer, 0); + if (buffer.Length != DefaultBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + + buffer = newBuffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendNewLine() + { + if (crlf) + { + if (buffer.Length - index < 2) Grow(2); + buffer[index] = newLine1; + buffer[index + 1] = newLine2; + index += 2; + } + else + { + if (buffer.Length - index < 1) Grow(1); + buffer[index] = newLine1; + index += 1; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string value) + { + var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); + if (buffer.Length - index < maxLen) + { + Grow(maxLen); + } + + index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string value) + { + Append(value); + AppendNewLine(); + } + + public void Append(T value) + { + if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + public void AppendLine(T value) + { + Append(value); + AppendNewLine(); + } + + // Output + + public bool TryCopyTo(Span destination, out int bytesWritten) + { + if (destination.Length < index) + { + bytesWritten = 0; + return false; + } + + bytesWritten = index; + buffer.AsSpan(0, index).CopyTo(destination); + return true; + } + + public Task CopyToAsync(Stream stream) + { + return stream.WriteAsync(buffer, 0, index); + } + + public override string ToString() + { + return UTF8NoBom.GetString(buffer, 0, index); + } + + // IBufferWriter like interface. + + public Span GetWritableBuffer(int sizeHint = 0) + { + if ((buffer.Length - index) < sizeHint) + { + Grow(sizeHint); + } + + return buffer.AsSpan(index); + } + + public void Advance(int count) + { + index += count; + } + + void ThrowArgumentException(string paramName) + { + throw new ArgumentException("Can't format argument.", paramName); + } + + void ThrowFormatException() + { + throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); + } + + static class FormatterCache + { + public static TryFormat TryFormatDelegate; + static FormatterCache() + { + var formatter = (TryFormat)CreateFormatter(typeof(T)); + if (formatter == null) + { + formatter = new TryFormat(TryFormatDefault); + } + + TryFormatDelegate = formatter; + } + + static bool TryFormatDefault(T value, Span dest, out int written, StandardFormat format) + { + if (value == null) + { + written = 0; + return true; + } + + var s = value.ToString(); + + // also use this length when result is false. + written = UTF8NoBom.GetMaxByteCount(s.Length); + if (dest.Length < written) + { + return false; + } + + written = UTF8NoBom.GetBytes(s, dest); + return true; + + } + } + } +} \ No newline at end of file diff --git a/src/ZString/ZString.Format.cs b/src/ZString/ZString.Format.cs new file mode 100644 index 00000000..f7c22c5a --- /dev/null +++ b/src/ZString/ZString.Format.cs @@ -0,0 +1,234 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + public static partial class ZString + { + public static string Format(ReadOnlySpan format, T0 arg0) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + } +} \ No newline at end of file diff --git a/src/ZString/ZString.Format.tt b/src/ZString/ZString.Format.tt new file mode 100644 index 00000000..ef850cf1 --- /dev/null +++ b/src/ZString/ZString.Format.tt @@ -0,0 +1,49 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + } + + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + } +#> +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + public static partial class ZString + { +<# for(var i = 1; i <= 16; i++) { #> + public static string Format<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + { + var sb = CreateStringBuilder(); + try + { + sb.AppendFormat(format, <#= CreateParameterNames(i) #>); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs new file mode 100644 index 00000000..3d9704c4 --- /dev/null +++ b/src/ZString/ZString.cs @@ -0,0 +1,19 @@ +namespace Cysharp.Text +{ + public static partial class ZString + { + public static Utf16ValueStringBuilder CreateStringBuilder() + { + var builder = new Utf16ValueStringBuilder(); + builder.Init(); + return builder; + } + + public static Utf8ValueStringBuilder CreateUtf8StringBuilder() + { + var builder = new Utf8ValueStringBuilder(); + builder.Init(); + return builder; + } + } +} diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj new file mode 100644 index 00000000..08aeccdd --- /dev/null +++ b/src/ZString/ZString.csproj @@ -0,0 +1,115 @@ + + + + + netstandard2.1 + Cysharp.Text + + + $(Version) + Cysharp + Cysharp + © Cysharp, Inc. + string; + Zero alloction StringBuilder for .NET Core and Unity. + https://github.com/Cysharp/ZString + $(PackageProjectUrl) + git + MIT + + + + + + + + + Utf16ValueStringBuilder.AppendMany.cs + TextTemplatingFileGenerator + + + Utf16ValueStringBuilder.CreateFormatter.cs + TextTemplatingFileGenerator + + + Utf16ValueStringBuilder.SpanFormattableAppend.cs + TextTemplatingFileGenerator + + + Utf8ValueStringBuilder.AppendFormat.cs + TextTemplatingFileGenerator + + + Utf8ValueStringBuilder.AppendMany.cs + TextTemplatingFileGenerator + + + Utf8ValueStringBuilder.CreateFormatter.cs + TextTemplatingFileGenerator + + + Utf8ValueStringBuilder.SpanFormattableAppend.cs + TextTemplatingFileGenerator + + + TextTemplatingFileGenerator + Utf16ValueStringBuilder.AppendFormat.cs + + + TextTemplatingFileGenerator + ZString.Format.cs + + + + + + True + True + Utf16ValueStringBuilder.AppendFormat.tt + + + Utf16ValueStringBuilder.AppendMany.tt + True + True + + + Utf16ValueStringBuilder.CreateFormatter.tt + True + True + + + True + True + Utf16ValueStringBuilder.SpanFormattableAppend.tt + + + True + True + Utf8ValueStringBuilder.AppendFormat.tt + + + True + True + Utf8ValueStringBuilder.AppendMany.tt + + + True + True + Utf8ValueStringBuilder.CreateFormatter.tt + + + True + True + Utf8ValueStringBuilder.SpanFormattableAppend.tt + + + True + True + ZString.Format.tt + + + + + + + diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs new file mode 100644 index 00000000..3f24879e --- /dev/null +++ b/tests/ZString.Tests/FormatTest.cs @@ -0,0 +1,23 @@ +using Cysharp.Text; +using FluentAssertions; +using System; +using Xunit; + +namespace ZStringTests +{ + public class FormatTest + { + void Test(string format, T0 t0, T1 t1) + { + var actual = ZString.Format(format, t0, t1); + var expected = string.Format(format, t0, t1); + actual.Should().Be(expected); + } + + [Fact] + public void EmptyFormat() + { + Test("", 100, 200); + } + } +} diff --git a/tests/ZString.Tests/ZString.Tests.csproj b/tests/ZString.Tests/ZString.Tests.csproj new file mode 100644 index 00000000..e62e5ab5 --- /dev/null +++ b/tests/ZString.Tests/ZString.Tests.csproj @@ -0,0 +1,29 @@ + + + + netcoreapp3.1 + + false + + ZStringTests + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + From 3c39ddb440f6e9daf80e1ec8cf752a790873ad92 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Mon, 3 Feb 2020 23:09:35 +0900 Subject: [PATCH 002/139] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe9bc9eb..fbff84a8 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ZString WIP -**Z**ero alloction **String**Builder for .NET Core and Unity. +**Z**ero Alloction **String**Builder for .NET Core and Unity. ```csharp using var sb = ZString.CreateStringBuilder(); From 9ad4bbe17b9f1528f7f2325d0a9498415e5f6f73 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Tue, 4 Feb 2020 01:41:24 +0900 Subject: [PATCH 003/139] enum formatting --- src/ZString/EnumUtil.cs | 47 ++++++++++++++++++++++++++ src/ZString/Utf16ValueStringBuilder.cs | 9 ++++- src/ZString/Utf8ValueStringBuilder.cs | 9 ++++- 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/ZString/EnumUtil.cs diff --git a/src/ZString/EnumUtil.cs b/src/ZString/EnumUtil.cs new file mode 100644 index 00000000..cd3fb847 --- /dev/null +++ b/src/ZString/EnumUtil.cs @@ -0,0 +1,47 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + internal static class EnumUtil + { + static readonly Dictionary names; + static readonly Dictionary utf8names; + + static EnumUtil() + { + var names = Enum.GetNames(typeof(T)); + var values = Enum.GetValues(typeof(T)); + var dict = new Dictionary(names.Length); + for (int i = 0; i < names.Length; i++) + { + dict.Add((T)values.GetValue(i), names[i]); + utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(names[i])); + } + } + + public static bool TryFormatUtf16(T value, Span dest, out int written, ReadOnlySpan _) + { + if (!names.TryGetValue(value, out var v)) + { + v = value.ToString(); + } + + written = v.Length; + return v.AsSpan().TryCopyTo(dest); + } + + public static bool TryFormatUtf8(T value, Span dest, out int written, StandardFormat _) + { + if (!utf8names.TryGetValue(value, out var v)) + { + v = Encoding.UTF8.GetBytes(value.ToString()); + } + + written = v.Length; + return v.AsSpan().TryCopyTo(dest); + } + } +} diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 59a63bbb..8df80547 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -201,7 +201,14 @@ static FormatterCache() var formatter = (TryFormat)CreateFormatter(typeof(T)); if (formatter == null) { - formatter = new TryFormat(TryFormatDefault); + if (typeof(T).IsEnum) + { + formatter = new TryFormat(EnumUtil.TryFormatUtf16); + } + else + { + formatter = new TryFormat(TryFormatDefault); + } } TryFormatDelegate = formatter; diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 7c124c49..ceee831b 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -210,7 +210,14 @@ static FormatterCache() var formatter = (TryFormat)CreateFormatter(typeof(T)); if (formatter == null) { - formatter = new TryFormat(TryFormatDefault); + if (typeof(T).IsEnum) + { + formatter = new TryFormat(EnumUtil.TryFormatUtf8); + } + else + { + formatter = new TryFormat(TryFormatDefault); + } } TryFormatDelegate = formatter; From d9d1f494ee2d30b0b0ee6c8acbca6054aa7fe6ba Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Tue, 4 Feb 2020 11:18:35 +0900 Subject: [PATCH 004/139] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fbff84a8..50e01974 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ZString WIP -**Z**ero Alloction **String**Builder for .NET Core and Unity. +**Z**ero Allocation **String**Builder for .NET Core and Unity. ```csharp using var sb = ZString.CreateStringBuilder(); From ec76c8f4dd93ac66df280764e3132c87b8b1a011 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 14:41:50 +0900 Subject: [PATCH 005/139] add netstandard2.0 shims --- src/ZString/Converter/Shims.cs | 645 ++++++++++++++++++ src/ZString/EnumUtil.cs | 11 +- src/ZString/FormatParser.cs | 4 +- ...Utf16ValueStringBuilder.CreateFormatter.cs | 60 +- ...Utf16ValueStringBuilder.CreateFormatter.tt | 4 +- ...alueStringBuilder.SpanFormattableAppend.cs | 60 +- ...alueStringBuilder.SpanFormattableAppend.tt | 4 +- src/ZString/Utf16ValueStringBuilder.cs | 10 +- .../Utf8ValueStringBuilder.CreateFormatter.cs | 60 +- .../Utf8ValueStringBuilder.CreateFormatter.tt | 4 +- ...alueStringBuilder.SpanFormattableAppend.cs | 60 +- ...alueStringBuilder.SpanFormattableAppend.tt | 4 +- src/ZString/Utf8ValueStringBuilder.cs | 9 +- src/ZString/ZString.csproj | 3 +- tests/ZString.Tests/ZString.Tests.csproj | 2 +- 15 files changed, 799 insertions(+), 141 deletions(-) create mode 100644 src/ZString/Converter/Shims.cs diff --git a/src/ZString/Converter/Shims.cs b/src/ZString/Converter/Shims.cs new file mode 100644 index 00000000..6bbc17bb --- /dev/null +++ b/src/ZString/Converter/Shims.cs @@ -0,0 +1,645 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ +#if NETSTANDARD2_0 + internal static class Int32 + { + /// 0 ~ 9 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNumber(char c) + { + return '0' <= c && c <= '9'; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Parse(ReadOnlySpan s) + { + var value = 0L; + var sign = 1; + + if (s[0] == '-') + { + sign = -1; + } + + for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) + { + if (!IsNumber(s[i])) + { + goto END; + } + + // long.MinValue causes overflow so use unchecked. + value = unchecked(value * 10 + ((byte)s[i] - '0')); + } + + END: + return checked((int)(unchecked(value * sign))); + } + } + + // TODO; + internal static class ShimsExtensions + { + public static int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) + { + // TODO: + throw new NotImplementedException(); + } + + public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + throw new NotImplementedException(); + } + } + +#endif +} + + +namespace Cysharp.Text +{ + /// + /// zero-allocate itoa, dtoa, atoi, atod converters. + /// + internal static class NumberConverter + { + /// 0 ~ 9 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNumber(byte c) + { + return (byte)'0' <= c && c <= (byte)'9'; + } + + /// + /// Is 0 ~ 9, '.', '+', '-'? + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNumberRepresentation(byte c) + { + switch (c) + { + case 43: // + + case 45: // - + case 46: // . + case 48: // 0 + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: // 9 + return true; + case 44: + case 47: + default: + return false; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte ReadSByte(byte[] bytes, int offset, out int readCount) + { + return checked((sbyte)ReadInt64(bytes, offset, out readCount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short ReadInt16(byte[] bytes, int offset, out int readCount) + { + return checked((short)ReadInt64(bytes, offset, out readCount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ReadInt32(byte[] bytes, int offset, out int readCount) + { + return checked((int)ReadInt64(bytes, offset, out readCount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long ReadInt64(byte[] bytes, int offset, out int readCount) + { + var value = 0L; + var sign = 1; + + if (bytes[offset] == '-') + { + sign = -1; + } + + for (int i = ((sign == -1) ? offset + 1 : offset); i < bytes.Length; i++) + { + if (!IsNumber(bytes[i])) + { + readCount = i - offset; + goto END; + } + + // long.MinValue causes overflow so use unchecked. + value = unchecked(value * 10 + (bytes[i] - '0')); + } + readCount = bytes.Length - offset; + + END: + return unchecked(value * sign); + } + + + + + + + + + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static byte ReadByte(byte[] bytes, int offset, out int readCount) + // { + // return checked((byte)ReadUInt64(bytes, offset, out readCount)); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static ushort ReadUInt16(byte[] bytes, int offset, out int readCount) + // { + // return checked((ushort)ReadUInt64(bytes, offset, out readCount)); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static uint ReadUInt32(byte[] bytes, int offset, out int readCount) + // { + // return checked((uint)ReadUInt64(bytes, offset, out readCount)); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static ulong ReadUInt64(byte[] bytes, int offset, out int readCount) + // { + // var value = 0UL; + + // for (int i = offset; i < bytes.Length; i++) + // { + // if (!IsNumber(bytes[i])) + // { + // readCount = i - offset; + // goto END; + // } + + // value = checked(value * 10 + (ulong)(bytes[i] - '0')); + // } + // readCount = bytes.Length - offset; + + // END: + // return value; + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static float ReadSingle(byte[] bytes, int offset, out int readCount) + // { + // return StringToDoubleConverter.ToSingle(bytes, offset, out readCount); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static double ReadDouble(byte[] bytes, int offset, out int readCount) + // { + // return StringToDoubleConverter.ToDouble(bytes, offset, out readCount); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteByte(ref byte[] buffer, int offset, byte value) + // { + // return WriteUInt64(ref buffer, offset, (ulong)value); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteUInt16(ref byte[] buffer, int offset, ushort value) + // { + // return WriteUInt64(ref buffer, offset, (ulong)value); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteUInt32(ref byte[] buffer, int offset, uint value) + // { + // return WriteUInt64(ref buffer, offset, (ulong)value); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteUInt64(ref byte[] buffer, int offset, ulong value) + // { + // var startOffset = offset; + + // ulong num1 = value, num2, num3, num4, num5, div; + + // if (num1 < 10000) + // { + // if (num1 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 1); goto L1; } + // if (num1 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 2); goto L2; } + // if (num1 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 3); goto L3; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 4); goto L4; + // } + // else + // { + // num2 = num1 / 10000; + // num1 -= num2 * 10000; + // if (num2 < 10000) + // { + // if (num2 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 5); goto L5; } + // if (num2 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 6); goto L6; } + // if (num2 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 7); goto L7; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 8); goto L8; + // } + // else + // { + // num3 = num2 / 10000; + // num2 -= num3 * 10000; + // if (num3 < 10000) + // { + // if (num3 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 9); goto L9; } + // if (num3 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 10); goto L10; } + // if (num3 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 11); goto L11; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 12); goto L12; + // } + // else + // { + // num4 = num3 / 10000; + // num3 -= num4 * 10000; + // if (num4 < 10000) + // { + // if (num4 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 13); goto L13; } + // if (num4 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 14); goto L14; } + // if (num4 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 15); goto L15; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 16); goto L16; + // } + // else + // { + // num5 = num4 / 10000; + // num4 -= num5 * 10000; + // if (num5 < 10000) + // { + // if (num5 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 17); goto L17; } + // if (num5 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 18); goto L18; } + // if (num5 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 19); goto L19; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 20); goto L20; + // } + // L20: + // buffer[offset++] = (byte)('0' + (div = (num5 * 8389UL) >> 23)); + // num5 -= div * 1000; + // L19: + // buffer[offset++] = (byte)('0' + (div = (num5 * 5243UL) >> 19)); + // num5 -= div * 100; + // L18: + // buffer[offset++] = (byte)('0' + (div = (num5 * 6554UL) >> 16)); + // num5 -= div * 10; + // L17: + // buffer[offset++] = (byte)('0' + (num5)); + // } + // L16: + // buffer[offset++] = (byte)('0' + (div = (num4 * 8389UL) >> 23)); + // num4 -= div * 1000; + // L15: + // buffer[offset++] = (byte)('0' + (div = (num4 * 5243UL) >> 19)); + // num4 -= div * 100; + // L14: + // buffer[offset++] = (byte)('0' + (div = (num4 * 6554UL) >> 16)); + // num4 -= div * 10; + // L13: + // buffer[offset++] = (byte)('0' + (num4)); + // } + // L12: + // buffer[offset++] = (byte)('0' + (div = (num3 * 8389UL) >> 23)); + // num3 -= div * 1000; + // L11: + // buffer[offset++] = (byte)('0' + (div = (num3 * 5243UL) >> 19)); + // num3 -= div * 100; + // L10: + // buffer[offset++] = (byte)('0' + (div = (num3 * 6554UL) >> 16)); + // num3 -= div * 10; + // L9: + // buffer[offset++] = (byte)('0' + (num3)); + // } + // L8: + // buffer[offset++] = (byte)('0' + (div = (num2 * 8389UL) >> 23)); + // num2 -= div * 1000; + // L7: + // buffer[offset++] = (byte)('0' + (div = (num2 * 5243UL) >> 19)); + // num2 -= div * 100; + // L6: + // buffer[offset++] = (byte)('0' + (div = (num2 * 6554UL) >> 16)); + // num2 -= div * 10; + // L5: + // buffer[offset++] = (byte)('0' + (num2)); + // } + // L4: + // buffer[offset++] = (byte)('0' + (div = (num1 * 8389UL) >> 23)); + // num1 -= div * 1000; + // L3: + // buffer[offset++] = (byte)('0' + (div = (num1 * 5243UL) >> 19)); + // num1 -= div * 100; + // L2: + // buffer[offset++] = (byte)('0' + (div = (num1 * 6554UL) >> 16)); + // num1 -= div * 10; + // L1: + // buffer[offset++] = (byte)('0' + (num1)); + + // return offset - startOffset; + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteSByte(ref byte[] buffer, int offset, sbyte value) + // { + // return WriteInt64(ref buffer, offset, (long)value); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteInt16(ref byte[] buffer, int offset, short value) + // { + // return WriteInt64(ref buffer, offset, (long)value); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteInt32(ref byte[] buffer, int offset, int value) + // { + // return WriteInt64(ref buffer, offset, (long)value); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteInt64(ref byte[] buffer, int offset, long value) + // { + // var startOffset = offset; + + // long num1 = value, num2, num3, num4, num5, div; + + // if (value < 0) + // { + // if (value == long.MinValue) // -9223372036854775808 + // { + // BinaryUtil.EnsureCapacity(ref buffer, offset, 20); + // buffer[offset++] = (byte)'-'; + // buffer[offset++] = (byte)'9'; + // buffer[offset++] = (byte)'2'; + // buffer[offset++] = (byte)'2'; + // buffer[offset++] = (byte)'3'; + // buffer[offset++] = (byte)'3'; + // buffer[offset++] = (byte)'7'; + // buffer[offset++] = (byte)'2'; + // buffer[offset++] = (byte)'0'; + // buffer[offset++] = (byte)'3'; + // buffer[offset++] = (byte)'6'; + // buffer[offset++] = (byte)'8'; + // buffer[offset++] = (byte)'5'; + // buffer[offset++] = (byte)'4'; + // buffer[offset++] = (byte)'7'; + // buffer[offset++] = (byte)'7'; + // buffer[offset++] = (byte)'5'; + // buffer[offset++] = (byte)'8'; + // buffer[offset++] = (byte)'0'; + // buffer[offset++] = (byte)'8'; + // return offset - startOffset; + // } + + // BinaryUtil.EnsureCapacity(ref buffer, offset, 1); + // buffer[offset++] = (byte)'-'; + // num1 = unchecked(-value); + // } + + // // WriteUInt64(inlined) + + // if (num1 < 10000) + // { + // if (num1 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 1); goto L1; } + // if (num1 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 2); goto L2; } + // if (num1 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 3); goto L3; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 4); goto L4; + // } + // else + // { + // num2 = num1 / 10000; + // num1 -= num2 * 10000; + // if (num2 < 10000) + // { + // if (num2 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 5); goto L5; } + // if (num2 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 6); goto L6; } + // if (num2 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 7); goto L7; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 8); goto L8; + // } + // else + // { + // num3 = num2 / 10000; + // num2 -= num3 * 10000; + // if (num3 < 10000) + // { + // if (num3 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 9); goto L9; } + // if (num3 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 10); goto L10; } + // if (num3 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 11); goto L11; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 12); goto L12; + // } + // else + // { + // num4 = num3 / 10000; + // num3 -= num4 * 10000; + // if (num4 < 10000) + // { + // if (num4 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 13); goto L13; } + // if (num4 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 14); goto L14; } + // if (num4 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 15); goto L15; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 16); goto L16; + // } + // else + // { + // num5 = num4 / 10000; + // num4 -= num5 * 10000; + // if (num5 < 10000) + // { + // if (num5 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 17); goto L17; } + // if (num5 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 18); goto L18; } + // if (num5 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 19); goto L19; } + // BinaryUtil.EnsureCapacity(ref buffer, offset, 20); goto L20; + // } + // L20: + // buffer[offset++] = (byte)('0' + (div = (num5 * 8389L) >> 23)); + // num5 -= div * 1000; + // L19: + // buffer[offset++] = (byte)('0' + (div = (num5 * 5243L) >> 19)); + // num5 -= div * 100; + // L18: + // buffer[offset++] = (byte)('0' + (div = (num5 * 6554L) >> 16)); + // num5 -= div * 10; + // L17: + // buffer[offset++] = (byte)('0' + (num5)); + // } + // L16: + // buffer[offset++] = (byte)('0' + (div = (num4 * 8389L) >> 23)); + // num4 -= div * 1000; + // L15: + // buffer[offset++] = (byte)('0' + (div = (num4 * 5243L) >> 19)); + // num4 -= div * 100; + // L14: + // buffer[offset++] = (byte)('0' + (div = (num4 * 6554L) >> 16)); + // num4 -= div * 10; + // L13: + // buffer[offset++] = (byte)('0' + (num4)); + // } + // L12: + // buffer[offset++] = (byte)('0' + (div = (num3 * 8389L) >> 23)); + // num3 -= div * 1000; + // L11: + // buffer[offset++] = (byte)('0' + (div = (num3 * 5243L) >> 19)); + // num3 -= div * 100; + // L10: + // buffer[offset++] = (byte)('0' + (div = (num3 * 6554L) >> 16)); + // num3 -= div * 10; + // L9: + // buffer[offset++] = (byte)('0' + (num3)); + // } + // L8: + // buffer[offset++] = (byte)('0' + (div = (num2 * 8389L) >> 23)); + // num2 -= div * 1000; + // L7: + // buffer[offset++] = (byte)('0' + (div = (num2 * 5243L) >> 19)); + // num2 -= div * 100; + // L6: + // buffer[offset++] = (byte)('0' + (div = (num2 * 6554L) >> 16)); + // num2 -= div * 10; + // L5: + // buffer[offset++] = (byte)('0' + (num2)); + // } + // L4: + // buffer[offset++] = (byte)('0' + (div = (num1 * 8389L) >> 23)); + // num1 -= div * 1000; + // L3: + // buffer[offset++] = (byte)('0' + (div = (num1 * 5243L) >> 19)); + // num1 -= div * 100; + // L2: + // buffer[offset++] = (byte)('0' + (div = (num1 * 6554L) >> 16)); + // num1 -= div * 10; + // L1: + // buffer[offset++] = (byte)('0' + (num1)); + + // return offset - startOffset; + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteSingle(ref byte[] bytes, int offset, float value) + // { + // return DoubleToStringConverter.GetBytes(ref bytes, offset, value); + // } + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static int WriteDouble(ref byte[] bytes, int offset, double value) + // { + // return DoubleToStringConverter.GetBytes(ref bytes, offset, value); + // } + + // // boolean is not number:) + + //#if NETSTANDARD + // [MethodImpl(MethodImplOptions.AggressiveInlining)] + //#endif + // public static bool ReadBoolean(byte[] bytes, int offset, out int readCount) + // { + // if (bytes[offset] == 't') + // { + // if (bytes[offset + 1] != 'r') goto ERROR_TRUE; + // if (bytes[offset + 2] != 'u') goto ERROR_TRUE; + // if (bytes[offset + 3] != 'e') goto ERROR_TRUE; + // readCount = 4; + // return true; + // } + // else if (bytes[offset] == 'f') + // { + // if (bytes[offset + 1] != 'a') goto ERROR_FALSE; + // if (bytes[offset + 2] != 'l') goto ERROR_FALSE; + // if (bytes[offset + 3] != 's') goto ERROR_FALSE; + // if (bytes[offset + 4] != 'e') goto ERROR_FALSE; + // readCount = 5; + // return false; + // } + // else + // { + // throw new InvalidOperationException("value is not boolean."); + // } + + // ERROR_TRUE: + // throw new InvalidOperationException("value is not boolean(true)."); + // ERROR_FALSE: + // throw new InvalidOperationException("value is not boolean(false)."); + // } + // } + } +} \ No newline at end of file diff --git a/src/ZString/EnumUtil.cs b/src/ZString/EnumUtil.cs index cd3fb847..2548474a 100644 --- a/src/ZString/EnumUtil.cs +++ b/src/ZString/EnumUtil.cs @@ -12,13 +12,14 @@ internal static class EnumUtil static EnumUtil() { - var names = Enum.GetNames(typeof(T)); + var enumNames = Enum.GetNames(typeof(T)); var values = Enum.GetValues(typeof(T)); - var dict = new Dictionary(names.Length); - for (int i = 0; i < names.Length; i++) + names = new Dictionary(enumNames.Length); + utf8names = new Dictionary(enumNames.Length); + for (int i = 0; i < enumNames.Length; i++) { - dict.Add((T)values.GetValue(i), names[i]); - utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(names[i])); + names.Add((T)values.GetValue(i), enumNames[i]); + utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i])); } } diff --git a/src/ZString/FormatParser.cs b/src/ZString/FormatParser.cs index 10d2bdee..9808ef47 100644 --- a/src/ZString/FormatParser.cs +++ b/src/ZString/FormatParser.cs @@ -32,7 +32,7 @@ public static ParseResult Parse(ReadOnlySpan format) { if (index == -1) { - index = int.Parse(format.Slice(1, i - 1)); + index = Int32.Parse(format.Slice(1, i - 1)); return new ParseResult(index, default, i); } else @@ -44,7 +44,7 @@ public static ParseResult Parse(ReadOnlySpan format) if (index == -1 && format[i] == ',' || format[i] == ':') { - index = int.Parse(format.Slice(1, i - 1)); + index = Int32.Parse(format.Slice(1, i - 1)); formatStart = i + 1; } } diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 7369e90e..63c24893 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -6,65 +6,65 @@ public ref partial struct Utf16ValueStringBuilder { static object CreateFormatter(Type type) { - if (type == typeof(Byte)) + if (type == typeof(System.Byte)) { - return new TryFormat((Byte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Byte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(DateTime)) + if (type == typeof(System.DateTime)) { - return new TryFormat((DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(DateTimeOffset)) + if (type == typeof(System.DateTimeOffset)) { - return new TryFormat((DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(Decimal)) + if (type == typeof(System.Decimal)) { - return new TryFormat((Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(Double)) + if (type == typeof(System.Double)) { - return new TryFormat((Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(Guid)) + if (type == typeof(System.Guid)) { - return new TryFormat((Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(Int16)) + if (type == typeof(System.Int16)) { - return new TryFormat((Int16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(Int32)) + if (type == typeof(System.Int32)) { - return new TryFormat((Int32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(Int64)) + if (type == typeof(System.Int64)) { - return new TryFormat((Int64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(SByte)) + if (type == typeof(System.SByte)) { - return new TryFormat((SByte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.SByte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(Single)) + if (type == typeof(System.Single)) { - return new TryFormat((Single x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Single x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(TimeSpan)) + if (type == typeof(System.TimeSpan)) { - return new TryFormat((TimeSpan x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.TimeSpan x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(UInt16)) + if (type == typeof(System.UInt16)) { - return new TryFormat((UInt16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(UInt32)) + if (type == typeof(System.UInt32)) { - return new TryFormat((UInt32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(UInt64)) + if (type == typeof(System.UInt64)) { - return new TryFormat((UInt64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } return null; diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt index 5e92382f..52591086 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt @@ -34,9 +34,9 @@ namespace Cysharp.Text static object CreateFormatter(Type type) { <# foreach(var t in spanFormattables) { #> - if (type == typeof(<#= t.Name #>)) + if (type == typeof(<#= t.FullName #>)) { - return new TryFormat<<#= t.Name #>>((<#= t.Name #> x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } <# } #> diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index 2401c2a8..f2713cd5 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -6,7 +6,7 @@ namespace Cysharp.Text public ref partial struct Utf16ValueStringBuilder { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Byte value) + public void Append(System.Byte value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -20,7 +20,7 @@ public void Append(Byte value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Byte value, ReadOnlySpan format) + public void Append(System.Byte value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -34,7 +34,7 @@ public void Append(Byte value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(DateTime value) + public void Append(System.DateTime value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -48,7 +48,7 @@ public void Append(DateTime value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(DateTime value, ReadOnlySpan format) + public void Append(System.DateTime value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -62,7 +62,7 @@ public void Append(DateTime value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(DateTimeOffset value) + public void Append(System.DateTimeOffset value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -76,7 +76,7 @@ public void Append(DateTimeOffset value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(DateTimeOffset value, ReadOnlySpan format) + public void Append(System.DateTimeOffset value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -90,7 +90,7 @@ public void Append(DateTimeOffset value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Decimal value) + public void Append(System.Decimal value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -104,7 +104,7 @@ public void Append(Decimal value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Decimal value, ReadOnlySpan format) + public void Append(System.Decimal value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -118,7 +118,7 @@ public void Append(Decimal value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Double value) + public void Append(System.Double value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -132,7 +132,7 @@ public void Append(Double value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Double value, ReadOnlySpan format) + public void Append(System.Double value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -146,7 +146,7 @@ public void Append(Double value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int16 value) + public void Append(System.Int16 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -160,7 +160,7 @@ public void Append(Int16 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int16 value, ReadOnlySpan format) + public void Append(System.Int16 value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -174,7 +174,7 @@ public void Append(Int16 value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int32 value) + public void Append(System.Int32 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -188,7 +188,7 @@ public void Append(Int32 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int32 value, ReadOnlySpan format) + public void Append(System.Int32 value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -202,7 +202,7 @@ public void Append(Int32 value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int64 value) + public void Append(System.Int64 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -216,7 +216,7 @@ public void Append(Int64 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int64 value, ReadOnlySpan format) + public void Append(System.Int64 value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -230,7 +230,7 @@ public void Append(Int64 value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(SByte value) + public void Append(System.SByte value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -244,7 +244,7 @@ public void Append(SByte value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(SByte value, ReadOnlySpan format) + public void Append(System.SByte value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -258,7 +258,7 @@ public void Append(SByte value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Single value) + public void Append(System.Single value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -272,7 +272,7 @@ public void Append(Single value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Single value, ReadOnlySpan format) + public void Append(System.Single value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -286,7 +286,7 @@ public void Append(Single value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(TimeSpan value) + public void Append(System.TimeSpan value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -300,7 +300,7 @@ public void Append(TimeSpan value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(TimeSpan value, ReadOnlySpan format) + public void Append(System.TimeSpan value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -314,7 +314,7 @@ public void Append(TimeSpan value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt16 value) + public void Append(System.UInt16 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -328,7 +328,7 @@ public void Append(UInt16 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt16 value, ReadOnlySpan format) + public void Append(System.UInt16 value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -342,7 +342,7 @@ public void Append(UInt16 value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt32 value) + public void Append(System.UInt32 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -356,7 +356,7 @@ public void Append(UInt32 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt32 value, ReadOnlySpan format) + public void Append(System.UInt32 value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -370,7 +370,7 @@ public void Append(UInt32 value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt64 value) + public void Append(System.UInt64 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -384,7 +384,7 @@ public void Append(UInt64 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt64 value, ReadOnlySpan format) + public void Append(System.UInt64 value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { @@ -398,7 +398,7 @@ public void Append(UInt64 value, ReadOnlySpan format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Guid value) + public void Append(System.Guid value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -412,7 +412,7 @@ public void Append(Guid value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Guid value, ReadOnlySpan format) + public void Append(System.Guid value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt index 8f443e74..6233dd6a 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt @@ -34,7 +34,7 @@ namespace Cysharp.Text { <# foreach(var t in spanFormattables) { #> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(<#= t.Name #> value) + public void Append(<#= t.FullName #> value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { @@ -48,7 +48,7 @@ namespace Cysharp.Text } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(<#= t.Name #> value, ReadOnlySpan format) + public void Append(<#= t.FullName #> value, ReadOnlySpan format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) { diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 8df80547..fb6b3a2c 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -6,7 +6,7 @@ namespace Cysharp.Text { public ref partial struct Utf16ValueStringBuilder { - delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); + public delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); const int DefaultBufferSize = 32768; // use 32K default buffer. @@ -40,6 +40,9 @@ static Utf16ValueStringBuilder() public int Length => index; public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + internal void Init() { @@ -193,6 +196,11 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + public static void RegisterTryFormat(TryFormat formatMethod) + { + FormatterCache.TryFormatDelegate = formatMethod; + } + static class FormatterCache { public static TryFormat TryFormatDelegate; diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index c4e83e77..2931b87e 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -8,65 +8,65 @@ public ref partial struct Utf8ValueStringBuilder { static object CreateFormatter(Type type) { - if (type == typeof(Byte)) + if (type == typeof(System.Byte)) { - return new TryFormat((Byte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.Byte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(DateTime)) + if (type == typeof(System.DateTime)) { - return new TryFormat((DateTime x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.DateTime x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(DateTimeOffset)) + if (type == typeof(System.DateTimeOffset)) { - return new TryFormat((DateTimeOffset x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.DateTimeOffset x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(Decimal)) + if (type == typeof(System.Decimal)) { - return new TryFormat((Decimal x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.Decimal x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(Double)) + if (type == typeof(System.Double)) { - return new TryFormat((Double x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.Double x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(Guid)) + if (type == typeof(System.Guid)) { - return new TryFormat((Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(Int16)) + if (type == typeof(System.Int16)) { - return new TryFormat((Int16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.Int16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(Int32)) + if (type == typeof(System.Int32)) { - return new TryFormat((Int32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.Int32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(Int64)) + if (type == typeof(System.Int64)) { - return new TryFormat((Int64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.Int64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(SByte)) + if (type == typeof(System.SByte)) { - return new TryFormat((SByte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.SByte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(Single)) + if (type == typeof(System.Single)) { - return new TryFormat((Single x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.Single x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(TimeSpan)) + if (type == typeof(System.TimeSpan)) { - return new TryFormat((TimeSpan x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.TimeSpan x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(UInt16)) + if (type == typeof(System.UInt16)) { - return new TryFormat((UInt16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.UInt16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(UInt32)) + if (type == typeof(System.UInt32)) { - return new TryFormat((UInt32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.UInt32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(UInt64)) + if (type == typeof(System.UInt64)) { - return new TryFormat((UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } return null; diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt index 81cf6000..e90e54d0 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt @@ -36,9 +36,9 @@ namespace Cysharp.Text static object CreateFormatter(Type type) { <# foreach(var t in spanFormattables) { #> - if (type == typeof(<#= t.Name #>)) + if (type == typeof(<#= t.FullName #>)) { - return new TryFormat<<#= t.Name #>>((<#= t.Name #> x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } <# } #> diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index 90856b21..2ea32b05 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -8,7 +8,7 @@ namespace Cysharp.Text public ref partial struct Utf8ValueStringBuilder { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Byte value) + public void Append(System.Byte value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -22,7 +22,7 @@ public void Append(Byte value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Byte value, StandardFormat format) + public void Append(System.Byte value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -36,7 +36,7 @@ public void Append(Byte value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(DateTime value) + public void Append(System.DateTime value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -50,7 +50,7 @@ public void Append(DateTime value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(DateTime value, StandardFormat format) + public void Append(System.DateTime value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -64,7 +64,7 @@ public void Append(DateTime value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(DateTimeOffset value) + public void Append(System.DateTimeOffset value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -78,7 +78,7 @@ public void Append(DateTimeOffset value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(DateTimeOffset value, StandardFormat format) + public void Append(System.DateTimeOffset value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -92,7 +92,7 @@ public void Append(DateTimeOffset value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Decimal value) + public void Append(System.Decimal value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -106,7 +106,7 @@ public void Append(Decimal value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Decimal value, StandardFormat format) + public void Append(System.Decimal value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -120,7 +120,7 @@ public void Append(Decimal value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Double value) + public void Append(System.Double value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -134,7 +134,7 @@ public void Append(Double value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Double value, StandardFormat format) + public void Append(System.Double value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -148,7 +148,7 @@ public void Append(Double value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int16 value) + public void Append(System.Int16 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -162,7 +162,7 @@ public void Append(Int16 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int16 value, StandardFormat format) + public void Append(System.Int16 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -176,7 +176,7 @@ public void Append(Int16 value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int32 value) + public void Append(System.Int32 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -190,7 +190,7 @@ public void Append(Int32 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int32 value, StandardFormat format) + public void Append(System.Int32 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -204,7 +204,7 @@ public void Append(Int32 value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int64 value) + public void Append(System.Int64 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -218,7 +218,7 @@ public void Append(Int64 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Int64 value, StandardFormat format) + public void Append(System.Int64 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -232,7 +232,7 @@ public void Append(Int64 value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(SByte value) + public void Append(System.SByte value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -246,7 +246,7 @@ public void Append(SByte value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(SByte value, StandardFormat format) + public void Append(System.SByte value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -260,7 +260,7 @@ public void Append(SByte value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Single value) + public void Append(System.Single value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -274,7 +274,7 @@ public void Append(Single value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Single value, StandardFormat format) + public void Append(System.Single value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -288,7 +288,7 @@ public void Append(Single value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(TimeSpan value) + public void Append(System.TimeSpan value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -302,7 +302,7 @@ public void Append(TimeSpan value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(TimeSpan value, StandardFormat format) + public void Append(System.TimeSpan value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -316,7 +316,7 @@ public void Append(TimeSpan value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt16 value) + public void Append(System.UInt16 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -330,7 +330,7 @@ public void Append(UInt16 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt16 value, StandardFormat format) + public void Append(System.UInt16 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -344,7 +344,7 @@ public void Append(UInt16 value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt32 value) + public void Append(System.UInt32 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -358,7 +358,7 @@ public void Append(UInt32 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt32 value, StandardFormat format) + public void Append(System.UInt32 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -372,7 +372,7 @@ public void Append(UInt32 value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt64 value) + public void Append(System.UInt64 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -386,7 +386,7 @@ public void Append(UInt64 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(UInt64 value, StandardFormat format) + public void Append(System.UInt64 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { @@ -400,7 +400,7 @@ public void Append(UInt64 value, StandardFormat format) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Guid value) + public void Append(System.Guid value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -414,7 +414,7 @@ public void Append(Guid value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Guid value, StandardFormat format) + public void Append(System.Guid value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt index 0025b409..c260b9c8 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt @@ -36,7 +36,7 @@ namespace Cysharp.Text { <# foreach(var t in spanFormattables) { #> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(<#= t.Name #> value) + public void Append(<#= t.FullName #> value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { @@ -50,7 +50,7 @@ namespace Cysharp.Text } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(<#= t.Name #> value, StandardFormat format) + public void Append(<#= t.FullName #> value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index ceee831b..ef18b01a 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -9,7 +9,7 @@ namespace Cysharp.Text { public ref partial struct Utf8ValueStringBuilder { - delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); + public delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); const int DefaultBufferSize = 65536; // use 64K default buffer. static Encoding UTF8NoBom = new UTF8Encoding(false); @@ -202,6 +202,11 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + public static void RegisterTryFormat(TryFormat formatMethod) + { + FormatterCache.TryFormatDelegate = formatMethod; + } + static class FormatterCache { public static TryFormat TryFormatDelegate; @@ -240,7 +245,7 @@ static bool TryFormatDefault(T value, Span dest, out int written, Standard return false; } - written = UTF8NoBom.GetBytes(s, dest); + written = UTF8NoBom.GetBytes(s.AsSpan(), dest); return true; } diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 08aeccdd..3526d30b 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -1,8 +1,7 @@  - - netstandard2.1 + netstandard2.1;netstandard2.0 Cysharp.Text diff --git a/tests/ZString.Tests/ZString.Tests.csproj b/tests/ZString.Tests/ZString.Tests.csproj index e62e5ab5..d9b5bb31 100644 --- a/tests/ZString.Tests/ZString.Tests.csproj +++ b/tests/ZString.Tests/ZString.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + netcoreapp3.1;netcoreapp2.1 false From f4a9467fab98c7862dff16e683e0d45010dc0160 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 14:46:05 +0900 Subject: [PATCH 006/139] fix Infinite Loop of AppendFormat #1 --- sandbox/ConsoleApp/Program.cs | 31 +-------- .../Utf16ValueStringBuilder.AppendFormat.cs | 64 +++++++++---------- .../Utf16ValueStringBuilder.AppendFormat.tt | 4 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 64 +++++++++---------- .../Utf8ValueStringBuilder.AppendFormat.tt | 4 +- 5 files changed, 70 insertions(+), 97 deletions(-) diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index bac97ba0..11ac3e00 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -12,36 +12,9 @@ static void Main(string[] args) static void Run() { - //using var sb = ZString.CreateStringBuilder(); - - //sb.AppendLine("foo"); - //sb.AppendLine(100); - //sb.AppendLine("baz"); - //sb.AppendLine(123.4); - //sb.AppendLine("foo", 999, "baz", 1000.4); - - //Console.WriteLine(sb.ToString()); - - //using var sb = ZString.CreateStringBuilder(); - - - //sb.Append(100); - //sb.Append(100, "hogehoge"); - //sb.Append(100, "hogehoge".AsSpan()); - - - //sb.AppendMany("hogehoge", 100, 300); - - - - using var sb2 = ZString.CreateUtf8StringBuilder(); - - sb2.Append("あ"); - sb2.Append(1999); - sb2.Append("bar"); - - Console.WriteLine(sb2.ToString()); + var f = ZString.Format("abcdef: {0}", "abc"); + Console.WriteLine(f); } } } diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index f83c2a57..2cca20e5 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -37,8 +37,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0) // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -117,8 +117,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -210,8 +210,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1 // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -316,8 +316,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -435,8 +435,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -567,8 +567,8 @@ public void AppendFormat(ReadOnlySpan format, T0 a // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -712,8 +712,8 @@ public void AppendFormat(ReadOnlySpan format, // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -870,8 +870,8 @@ public void AppendFormat(ReadOnlySpan form // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -1041,8 +1041,8 @@ public void AppendFormat(ReadOnlySpan // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -1225,8 +1225,8 @@ public void AppendFormat(ReadOnlySpan(ReadOnlySp // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -1632,8 +1632,8 @@ public void AppendFormat(ReadO // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -1855,8 +1855,8 @@ public void AppendFormat( // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -2091,8 +2091,8 @@ public void AppendFormat diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index ad0677c1..20fb6fff 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -35,8 +35,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0) // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -112,8 +112,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -202,8 +202,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1 // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -305,8 +305,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -421,8 +421,8 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -550,8 +550,8 @@ public void AppendFormat(ReadOnlySpan format, T0 a // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -692,8 +692,8 @@ public void AppendFormat(ReadOnlySpan format, // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -847,8 +847,8 @@ public void AppendFormat(ReadOnlySpan form // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -1015,8 +1015,8 @@ public void AppendFormat(ReadOnlySpan // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -1196,8 +1196,8 @@ public void AppendFormat(ReadOnlySpan(ReadOnlySp // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -1597,8 +1597,8 @@ public void AppendFormat(ReadO // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -1817,8 +1817,8 @@ public void AppendFormat( // try to find range var indexParse = FormatParser.Parse(format.Slice(i)); - copyFrom = indexParse.LastIndex + 1; - i = indexParse.LastIndex; + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; switch (indexParse.Index) { case 0: @@ -2050,8 +2050,8 @@ public void AppendFormat From 2413faf6319ee39ed03a2b7917ba0e1c487129f3 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 20:49:08 +0900 Subject: [PATCH 007/139] netstandard2 and tests --- .circleci/config.yml | 26 +- ZString.sln | 14 + sandbox/ConsoleApp/Program.cs | 11 +- sandbox/ConsoleAppNet472/App.config | 22 + .../ConsoleAppNet472/ConsoleAppNet472.csproj | 73 ++ sandbox/ConsoleAppNet472/Program.cs | 32 + .../Properties/AssemblyInfo.cs | 36 + sandbox/ConsoleAppNet472/packages.config | 7 + src/ZString/Converter/Shims.cs | 645 ------------- src/ZString/Shims/DoubleConversion/DiyFp.cs | 123 +++ .../DoubleToStringConverter.cs | 890 ++++++++++++++++++ src/ZString/Shims/DoubleConversion/IEEE.cs | 441 +++++++++ .../DoubleConversion/PowersOfTenCache.cs | 154 +++ .../Shims/DoubleConversion/StringToDouble.cs | 535 +++++++++++ .../StringToDoubleConverter.cs | 625 ++++++++++++ src/ZString/Shims/Shims.cs | 482 ++++++++++ .../Utf16ValueStringBuilder.AppendFormat.cs | 192 ++-- .../Utf16ValueStringBuilder.AppendFormat.tt | 12 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 192 ++-- .../Utf8ValueStringBuilder.AppendFormat.tt | 12 +- src/ZString/ZString.Format.cs | 32 +- src/ZString/ZString.Format.tt | 2 +- src/ZString/ZString.csproj | 6 +- src/ZString/_InternalVisibleTo.cs | 6 + .../ZString.NetCore2Tests.csproj | 31 + tests/ZString.Tests/FormatTest.cs | 2 +- tests/ZString.Tests/ZString.Tests.csproj | 4 +- 27 files changed, 3729 insertions(+), 878 deletions(-) create mode 100644 sandbox/ConsoleAppNet472/App.config create mode 100644 sandbox/ConsoleAppNet472/ConsoleAppNet472.csproj create mode 100644 sandbox/ConsoleAppNet472/Program.cs create mode 100644 sandbox/ConsoleAppNet472/Properties/AssemblyInfo.cs create mode 100644 sandbox/ConsoleAppNet472/packages.config delete mode 100644 src/ZString/Converter/Shims.cs create mode 100644 src/ZString/Shims/DoubleConversion/DiyFp.cs create mode 100644 src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs create mode 100644 src/ZString/Shims/DoubleConversion/IEEE.cs create mode 100644 src/ZString/Shims/DoubleConversion/PowersOfTenCache.cs create mode 100644 src/ZString/Shims/DoubleConversion/StringToDouble.cs create mode 100644 src/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs create mode 100644 src/ZString/Shims/Shims.cs create mode 100644 src/ZString/_InternalVisibleTo.cs create mode 100644 tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj diff --git a/.circleci/config.yml b/.circleci/config.yml index db79ede6..05544968 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,19 +6,31 @@ executors: environment: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true NUGET_XMLDOC_MODE: skip + dotnet2: + docker: + - image: mcr.microsoft.com/dotnet/core/sdk:2.1 + environment: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + NUGET_XMLDOC_MODE: skip jobs: build-test: executor: dotnet steps: - checkout - - run: dotnet build -c Debug - - run: dotnet test -c Debug --no-build < /dev/null + - run: dotnet build src/ZString -c Debug + - run: dotnet dotnet test tests/ZString.Tests -c Debug < /dev/null + test-netcore2: + executor: dotnet2 + steps: + - checkout + - run: dotnet dotnet test tests/ZString.NetCore2Tests -c Debug < /dev/null build-push: executor: dotnet steps: - checkout - - run: dotnet build -c Release -p:Version=${CIRCLE_TAG} - - run: dotnet test -c Release --no-build < /dev/null + - run: dotnet build src/ZString -c Release -p:Version=${CIRCLE_TAG} + - run: dotnet build tests/ZString.Tests -c Release -p:Version=${CIRCLE_TAG} + - run: dotnet test tests/ZString.Tests -c Release --no-build < /dev/null - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${CIRCLE_TAG} - store_artifacts: path: src/ZString/bin/Release/ @@ -26,12 +38,16 @@ jobs: - run: dotnet nuget push ./src/ZString/bin/Release/ZString.${CIRCLE_TAG}.nupkg -s https://www.nuget.org/api/v2/package -k ${NUGET_KEY} workflows: version: 2 - build-and-push: + default-pipeline: jobs: - build-test: filters: tags: only: /.*/ + - test-netcore2: + filters: + tags: + only: /.*/ - build-push: filters: tags: diff --git a/ZString.sln b/ZString.sln index e1cf5aac..ba5aa221 100644 --- a/ZString.sln +++ b/ZString.sln @@ -23,6 +23,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "sandbox\Conso EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZString.Tests", "tests\ZString.Tests\ZString.Tests.csproj", "{62090C00-9727-4375-BE40-ABE2F4D41571}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppNet472", "sandbox\ConsoleAppNet472\ConsoleAppNet472.csproj", "{BE8A17AA-504A-410D-B86D-92431B0F5594}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZString.NetCore2Tests", "tests\ZString.NetCore2Tests\ZString.NetCore2Tests.csproj", "{62C44156-F55C-4006-B9A2-108DAB340FAC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -41,6 +45,14 @@ Global {62090C00-9727-4375-BE40-ABE2F4D41571}.Debug|Any CPU.Build.0 = Debug|Any CPU {62090C00-9727-4375-BE40-ABE2F4D41571}.Release|Any CPU.ActiveCfg = Release|Any CPU {62090C00-9727-4375-BE40-ABE2F4D41571}.Release|Any CPU.Build.0 = Release|Any CPU + {BE8A17AA-504A-410D-B86D-92431B0F5594}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE8A17AA-504A-410D-B86D-92431B0F5594}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE8A17AA-504A-410D-B86D-92431B0F5594}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE8A17AA-504A-410D-B86D-92431B0F5594}.Release|Any CPU.Build.0 = Release|Any CPU + {62C44156-F55C-4006-B9A2-108DAB340FAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62C44156-F55C-4006-B9A2-108DAB340FAC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62C44156-F55C-4006-B9A2-108DAB340FAC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62C44156-F55C-4006-B9A2-108DAB340FAC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -49,6 +61,8 @@ Global {7B09D422-D19A-457E-ADA0-4CDC2DC581BB} = {B385367D-2EB5-49B3-A3EF-922151EC1904} {9ADF67E1-1872-43D3-882E-607071726FE7} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} {62090C00-9727-4375-BE40-ABE2F4D41571} = {0803618F-C4E8-4D37-831E-5D26C5574F49} + {BE8A17AA-504A-410D-B86D-92431B0F5594} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} + {62C44156-F55C-4006-B9A2-108DAB340FAC} = {0803618F-C4E8-4D37-831E-5D26C5574F49} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DF39BF43-3E0E-4F7D-9943-7E50D301234D} diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index 11ac3e00..b86c1965 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -12,9 +12,16 @@ static void Main(string[] args) static void Run() { - var f = ZString.Format("abcdef: {0}", "abc"); + //var f = ZString.Format("abcdef: {0}", "abc"); + //Console.WriteLine(f); + + + //Span buffer = stackalloc char[30]; + + //var ok = ShimsExtensions.TryWriteUInt64(buffer, out var written, 98321412421UL); + //Console.WriteLine(ok); + //Console.WriteLine(written); - Console.WriteLine(f); } } } diff --git a/sandbox/ConsoleAppNet472/App.config b/sandbox/ConsoleAppNet472/App.config new file mode 100644 index 00000000..dad5d67d --- /dev/null +++ b/sandbox/ConsoleAppNet472/App.config @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sandbox/ConsoleAppNet472/ConsoleAppNet472.csproj b/sandbox/ConsoleAppNet472/ConsoleAppNet472.csproj new file mode 100644 index 00000000..5e8a2c60 --- /dev/null +++ b/sandbox/ConsoleAppNet472/ConsoleAppNet472.csproj @@ -0,0 +1,73 @@ + + + + + Debug + AnyCPU + {BE8A17AA-504A-410D-B86D-92431B0F5594} + Exe + ConsoleAppNet472 + ConsoleAppNet472 + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + ..\..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll + + + + ..\..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + + ..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + + + + + + + + + + + + + + + + + {7b09d422-d19a-457e-ada0-4cdc2dc581bb} + ZString + + + + \ No newline at end of file diff --git a/sandbox/ConsoleAppNet472/Program.cs b/sandbox/ConsoleAppNet472/Program.cs new file mode 100644 index 00000000..cf5431d9 --- /dev/null +++ b/sandbox/ConsoleAppNet472/Program.cs @@ -0,0 +1,32 @@ +using Cysharp.Text; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConsoleAppNet472 +{ + class Program + { + static void Main(string[] args) + { + //double d = double.Epsilon; + //Span s = stackalloc char[128]; + + //var ok = ShimsExtensions.TryFormat(d, s, out var written); + //Console.WriteLine(ok); + //Console.WriteLine(written); + //Console.WriteLine(new string(s.Slice(written).ToArray())); + + // ReadOnlySpan hoge = "hugahuga"; + var tako = ZString.Format("hoge{0}hoge{1}", 100, 200); + + // new Utf8ValueStringBuilder(). + + + Console.WriteLine(tako); + + } + } +} diff --git a/sandbox/ConsoleAppNet472/Properties/AssemblyInfo.cs b/sandbox/ConsoleAppNet472/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..619a7fc4 --- /dev/null +++ b/sandbox/ConsoleAppNet472/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// 制御されます。アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更します。 +[assembly: AssemblyTitle("ConsoleAppNet472")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ConsoleAppNet472")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから +// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 +// その型の ComVisible 属性を true に設定します。 +[assembly: ComVisible(false)] + +// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります +[assembly: Guid("be8a17aa-504a-410d-b86d-92431b0f5594")] + +// アセンブリのバージョン情報は次の 4 つの値で構成されています: +// +// メジャー バージョン +// マイナー バージョン +// ビルド番号 +// リビジョン +// +// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます +// 既定値にすることができます: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/sandbox/ConsoleAppNet472/packages.config b/sandbox/ConsoleAppNet472/packages.config new file mode 100644 index 00000000..7de31c0d --- /dev/null +++ b/sandbox/ConsoleAppNet472/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/ZString/Converter/Shims.cs b/src/ZString/Converter/Shims.cs deleted file mode 100644 index 6bbc17bb..00000000 --- a/src/ZString/Converter/Shims.cs +++ /dev/null @@ -1,645 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ -#if NETSTANDARD2_0 - internal static class Int32 - { - /// 0 ~ 9 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsNumber(char c) - { - return '0' <= c && c <= '9'; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Parse(ReadOnlySpan s) - { - var value = 0L; - var sign = 1; - - if (s[0] == '-') - { - sign = -1; - } - - for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) - { - if (!IsNumber(s[i])) - { - goto END; - } - - // long.MinValue causes overflow so use unchecked. - value = unchecked(value * 10 + ((byte)s[i] - '0')); - } - - END: - return checked((int)(unchecked(value * sign))); - } - } - - // TODO; - internal static class ShimsExtensions - { - public static int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) - { - // TODO: - throw new NotImplementedException(); - } - - public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - throw new NotImplementedException(); - } - } - -#endif -} - - -namespace Cysharp.Text -{ - /// - /// zero-allocate itoa, dtoa, atoi, atod converters. - /// - internal static class NumberConverter - { - /// 0 ~ 9 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsNumber(byte c) - { - return (byte)'0' <= c && c <= (byte)'9'; - } - - /// - /// Is 0 ~ 9, '.', '+', '-'? - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsNumberRepresentation(byte c) - { - switch (c) - { - case 43: // + - case 45: // - - case 46: // . - case 48: // 0 - case 49: - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 56: - case 57: // 9 - return true; - case 44: - case 47: - default: - return false; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static sbyte ReadSByte(byte[] bytes, int offset, out int readCount) - { - return checked((sbyte)ReadInt64(bytes, offset, out readCount)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static short ReadInt16(byte[] bytes, int offset, out int readCount) - { - return checked((short)ReadInt64(bytes, offset, out readCount)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ReadInt32(byte[] bytes, int offset, out int readCount) - { - return checked((int)ReadInt64(bytes, offset, out readCount)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static long ReadInt64(byte[] bytes, int offset, out int readCount) - { - var value = 0L; - var sign = 1; - - if (bytes[offset] == '-') - { - sign = -1; - } - - for (int i = ((sign == -1) ? offset + 1 : offset); i < bytes.Length; i++) - { - if (!IsNumber(bytes[i])) - { - readCount = i - offset; - goto END; - } - - // long.MinValue causes overflow so use unchecked. - value = unchecked(value * 10 + (bytes[i] - '0')); - } - readCount = bytes.Length - offset; - - END: - return unchecked(value * sign); - } - - - - - - - - - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static byte ReadByte(byte[] bytes, int offset, out int readCount) - // { - // return checked((byte)ReadUInt64(bytes, offset, out readCount)); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static ushort ReadUInt16(byte[] bytes, int offset, out int readCount) - // { - // return checked((ushort)ReadUInt64(bytes, offset, out readCount)); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static uint ReadUInt32(byte[] bytes, int offset, out int readCount) - // { - // return checked((uint)ReadUInt64(bytes, offset, out readCount)); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static ulong ReadUInt64(byte[] bytes, int offset, out int readCount) - // { - // var value = 0UL; - - // for (int i = offset; i < bytes.Length; i++) - // { - // if (!IsNumber(bytes[i])) - // { - // readCount = i - offset; - // goto END; - // } - - // value = checked(value * 10 + (ulong)(bytes[i] - '0')); - // } - // readCount = bytes.Length - offset; - - // END: - // return value; - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static float ReadSingle(byte[] bytes, int offset, out int readCount) - // { - // return StringToDoubleConverter.ToSingle(bytes, offset, out readCount); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static double ReadDouble(byte[] bytes, int offset, out int readCount) - // { - // return StringToDoubleConverter.ToDouble(bytes, offset, out readCount); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteByte(ref byte[] buffer, int offset, byte value) - // { - // return WriteUInt64(ref buffer, offset, (ulong)value); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteUInt16(ref byte[] buffer, int offset, ushort value) - // { - // return WriteUInt64(ref buffer, offset, (ulong)value); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteUInt32(ref byte[] buffer, int offset, uint value) - // { - // return WriteUInt64(ref buffer, offset, (ulong)value); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteUInt64(ref byte[] buffer, int offset, ulong value) - // { - // var startOffset = offset; - - // ulong num1 = value, num2, num3, num4, num5, div; - - // if (num1 < 10000) - // { - // if (num1 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 1); goto L1; } - // if (num1 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 2); goto L2; } - // if (num1 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 3); goto L3; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 4); goto L4; - // } - // else - // { - // num2 = num1 / 10000; - // num1 -= num2 * 10000; - // if (num2 < 10000) - // { - // if (num2 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 5); goto L5; } - // if (num2 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 6); goto L6; } - // if (num2 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 7); goto L7; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 8); goto L8; - // } - // else - // { - // num3 = num2 / 10000; - // num2 -= num3 * 10000; - // if (num3 < 10000) - // { - // if (num3 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 9); goto L9; } - // if (num3 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 10); goto L10; } - // if (num3 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 11); goto L11; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 12); goto L12; - // } - // else - // { - // num4 = num3 / 10000; - // num3 -= num4 * 10000; - // if (num4 < 10000) - // { - // if (num4 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 13); goto L13; } - // if (num4 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 14); goto L14; } - // if (num4 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 15); goto L15; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 16); goto L16; - // } - // else - // { - // num5 = num4 / 10000; - // num4 -= num5 * 10000; - // if (num5 < 10000) - // { - // if (num5 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 17); goto L17; } - // if (num5 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 18); goto L18; } - // if (num5 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 19); goto L19; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 20); goto L20; - // } - // L20: - // buffer[offset++] = (byte)('0' + (div = (num5 * 8389UL) >> 23)); - // num5 -= div * 1000; - // L19: - // buffer[offset++] = (byte)('0' + (div = (num5 * 5243UL) >> 19)); - // num5 -= div * 100; - // L18: - // buffer[offset++] = (byte)('0' + (div = (num5 * 6554UL) >> 16)); - // num5 -= div * 10; - // L17: - // buffer[offset++] = (byte)('0' + (num5)); - // } - // L16: - // buffer[offset++] = (byte)('0' + (div = (num4 * 8389UL) >> 23)); - // num4 -= div * 1000; - // L15: - // buffer[offset++] = (byte)('0' + (div = (num4 * 5243UL) >> 19)); - // num4 -= div * 100; - // L14: - // buffer[offset++] = (byte)('0' + (div = (num4 * 6554UL) >> 16)); - // num4 -= div * 10; - // L13: - // buffer[offset++] = (byte)('0' + (num4)); - // } - // L12: - // buffer[offset++] = (byte)('0' + (div = (num3 * 8389UL) >> 23)); - // num3 -= div * 1000; - // L11: - // buffer[offset++] = (byte)('0' + (div = (num3 * 5243UL) >> 19)); - // num3 -= div * 100; - // L10: - // buffer[offset++] = (byte)('0' + (div = (num3 * 6554UL) >> 16)); - // num3 -= div * 10; - // L9: - // buffer[offset++] = (byte)('0' + (num3)); - // } - // L8: - // buffer[offset++] = (byte)('0' + (div = (num2 * 8389UL) >> 23)); - // num2 -= div * 1000; - // L7: - // buffer[offset++] = (byte)('0' + (div = (num2 * 5243UL) >> 19)); - // num2 -= div * 100; - // L6: - // buffer[offset++] = (byte)('0' + (div = (num2 * 6554UL) >> 16)); - // num2 -= div * 10; - // L5: - // buffer[offset++] = (byte)('0' + (num2)); - // } - // L4: - // buffer[offset++] = (byte)('0' + (div = (num1 * 8389UL) >> 23)); - // num1 -= div * 1000; - // L3: - // buffer[offset++] = (byte)('0' + (div = (num1 * 5243UL) >> 19)); - // num1 -= div * 100; - // L2: - // buffer[offset++] = (byte)('0' + (div = (num1 * 6554UL) >> 16)); - // num1 -= div * 10; - // L1: - // buffer[offset++] = (byte)('0' + (num1)); - - // return offset - startOffset; - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteSByte(ref byte[] buffer, int offset, sbyte value) - // { - // return WriteInt64(ref buffer, offset, (long)value); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteInt16(ref byte[] buffer, int offset, short value) - // { - // return WriteInt64(ref buffer, offset, (long)value); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteInt32(ref byte[] buffer, int offset, int value) - // { - // return WriteInt64(ref buffer, offset, (long)value); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteInt64(ref byte[] buffer, int offset, long value) - // { - // var startOffset = offset; - - // long num1 = value, num2, num3, num4, num5, div; - - // if (value < 0) - // { - // if (value == long.MinValue) // -9223372036854775808 - // { - // BinaryUtil.EnsureCapacity(ref buffer, offset, 20); - // buffer[offset++] = (byte)'-'; - // buffer[offset++] = (byte)'9'; - // buffer[offset++] = (byte)'2'; - // buffer[offset++] = (byte)'2'; - // buffer[offset++] = (byte)'3'; - // buffer[offset++] = (byte)'3'; - // buffer[offset++] = (byte)'7'; - // buffer[offset++] = (byte)'2'; - // buffer[offset++] = (byte)'0'; - // buffer[offset++] = (byte)'3'; - // buffer[offset++] = (byte)'6'; - // buffer[offset++] = (byte)'8'; - // buffer[offset++] = (byte)'5'; - // buffer[offset++] = (byte)'4'; - // buffer[offset++] = (byte)'7'; - // buffer[offset++] = (byte)'7'; - // buffer[offset++] = (byte)'5'; - // buffer[offset++] = (byte)'8'; - // buffer[offset++] = (byte)'0'; - // buffer[offset++] = (byte)'8'; - // return offset - startOffset; - // } - - // BinaryUtil.EnsureCapacity(ref buffer, offset, 1); - // buffer[offset++] = (byte)'-'; - // num1 = unchecked(-value); - // } - - // // WriteUInt64(inlined) - - // if (num1 < 10000) - // { - // if (num1 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 1); goto L1; } - // if (num1 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 2); goto L2; } - // if (num1 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 3); goto L3; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 4); goto L4; - // } - // else - // { - // num2 = num1 / 10000; - // num1 -= num2 * 10000; - // if (num2 < 10000) - // { - // if (num2 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 5); goto L5; } - // if (num2 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 6); goto L6; } - // if (num2 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 7); goto L7; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 8); goto L8; - // } - // else - // { - // num3 = num2 / 10000; - // num2 -= num3 * 10000; - // if (num3 < 10000) - // { - // if (num3 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 9); goto L9; } - // if (num3 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 10); goto L10; } - // if (num3 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 11); goto L11; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 12); goto L12; - // } - // else - // { - // num4 = num3 / 10000; - // num3 -= num4 * 10000; - // if (num4 < 10000) - // { - // if (num4 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 13); goto L13; } - // if (num4 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 14); goto L14; } - // if (num4 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 15); goto L15; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 16); goto L16; - // } - // else - // { - // num5 = num4 / 10000; - // num4 -= num5 * 10000; - // if (num5 < 10000) - // { - // if (num5 < 10) { BinaryUtil.EnsureCapacity(ref buffer, offset, 17); goto L17; } - // if (num5 < 100) { BinaryUtil.EnsureCapacity(ref buffer, offset, 18); goto L18; } - // if (num5 < 1000) { BinaryUtil.EnsureCapacity(ref buffer, offset, 19); goto L19; } - // BinaryUtil.EnsureCapacity(ref buffer, offset, 20); goto L20; - // } - // L20: - // buffer[offset++] = (byte)('0' + (div = (num5 * 8389L) >> 23)); - // num5 -= div * 1000; - // L19: - // buffer[offset++] = (byte)('0' + (div = (num5 * 5243L) >> 19)); - // num5 -= div * 100; - // L18: - // buffer[offset++] = (byte)('0' + (div = (num5 * 6554L) >> 16)); - // num5 -= div * 10; - // L17: - // buffer[offset++] = (byte)('0' + (num5)); - // } - // L16: - // buffer[offset++] = (byte)('0' + (div = (num4 * 8389L) >> 23)); - // num4 -= div * 1000; - // L15: - // buffer[offset++] = (byte)('0' + (div = (num4 * 5243L) >> 19)); - // num4 -= div * 100; - // L14: - // buffer[offset++] = (byte)('0' + (div = (num4 * 6554L) >> 16)); - // num4 -= div * 10; - // L13: - // buffer[offset++] = (byte)('0' + (num4)); - // } - // L12: - // buffer[offset++] = (byte)('0' + (div = (num3 * 8389L) >> 23)); - // num3 -= div * 1000; - // L11: - // buffer[offset++] = (byte)('0' + (div = (num3 * 5243L) >> 19)); - // num3 -= div * 100; - // L10: - // buffer[offset++] = (byte)('0' + (div = (num3 * 6554L) >> 16)); - // num3 -= div * 10; - // L9: - // buffer[offset++] = (byte)('0' + (num3)); - // } - // L8: - // buffer[offset++] = (byte)('0' + (div = (num2 * 8389L) >> 23)); - // num2 -= div * 1000; - // L7: - // buffer[offset++] = (byte)('0' + (div = (num2 * 5243L) >> 19)); - // num2 -= div * 100; - // L6: - // buffer[offset++] = (byte)('0' + (div = (num2 * 6554L) >> 16)); - // num2 -= div * 10; - // L5: - // buffer[offset++] = (byte)('0' + (num2)); - // } - // L4: - // buffer[offset++] = (byte)('0' + (div = (num1 * 8389L) >> 23)); - // num1 -= div * 1000; - // L3: - // buffer[offset++] = (byte)('0' + (div = (num1 * 5243L) >> 19)); - // num1 -= div * 100; - // L2: - // buffer[offset++] = (byte)('0' + (div = (num1 * 6554L) >> 16)); - // num1 -= div * 10; - // L1: - // buffer[offset++] = (byte)('0' + (num1)); - - // return offset - startOffset; - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteSingle(ref byte[] bytes, int offset, float value) - // { - // return DoubleToStringConverter.GetBytes(ref bytes, offset, value); - // } - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static int WriteDouble(ref byte[] bytes, int offset, double value) - // { - // return DoubleToStringConverter.GetBytes(ref bytes, offset, value); - // } - - // // boolean is not number:) - - //#if NETSTANDARD - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - //#endif - // public static bool ReadBoolean(byte[] bytes, int offset, out int readCount) - // { - // if (bytes[offset] == 't') - // { - // if (bytes[offset + 1] != 'r') goto ERROR_TRUE; - // if (bytes[offset + 2] != 'u') goto ERROR_TRUE; - // if (bytes[offset + 3] != 'e') goto ERROR_TRUE; - // readCount = 4; - // return true; - // } - // else if (bytes[offset] == 'f') - // { - // if (bytes[offset + 1] != 'a') goto ERROR_FALSE; - // if (bytes[offset + 2] != 'l') goto ERROR_FALSE; - // if (bytes[offset + 3] != 's') goto ERROR_FALSE; - // if (bytes[offset + 4] != 'e') goto ERROR_FALSE; - // readCount = 5; - // return false; - // } - // else - // { - // throw new InvalidOperationException("value is not boolean."); - // } - - // ERROR_TRUE: - // throw new InvalidOperationException("value is not boolean(true)."); - // ERROR_FALSE: - // throw new InvalidOperationException("value is not boolean(false)."); - // } - // } - } -} \ No newline at end of file diff --git a/src/ZString/Shims/DoubleConversion/DiyFp.cs b/src/ZString/Shims/DoubleConversion/DiyFp.cs new file mode 100644 index 00000000..b10835bf --- /dev/null +++ b/src/ZString/Shims/DoubleConversion/DiyFp.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text.Internal +{ + // https://github.com/google/double-conversion/blob/master/double-conversion/diy-fp.cc + // https://github.com/google/double-conversion/blob/master/double-conversion/diy-fp.h + + internal struct DiyFp + { + public const int kSignificandSize = 64; + public const ulong kUint64MSB = 0x8000000000000000; // 0x80000000_00000000; + + // uint64_t f_; + // int e_; + // long f() const { return f_; } + // int e() const { return e_; } + // void set_f(long new_value) { f_ = new_value; } + // void set_e(int new_value) { e_ = new_value; } + + // public field, not safe... + public ulong f; + public int e; + + public DiyFp(ulong significand, int exponent) + { + this.f = significand; + this.e = exponent; + } + + // this = this - other. + // The exponents of both numbers must be the same and the significand of this + // must be bigger than the significand of other. + // The result will not be normalized. + public void Subtract(ref DiyFp other) + { + f -= other.f; + } + + // Returns a - b. + // The exponents of both numbers must be the same and this must be bigger + // than other. The result will not be normalized. + public static DiyFp Minus(ref DiyFp a, ref DiyFp b) + { + DiyFp result = a; + result.Subtract(ref b); + return result; + } + + public static DiyFp operator -(DiyFp lhs, DiyFp rhs) + { + return Minus(ref lhs, ref rhs); + } + + // this = this * other. + public void Multiply(ref DiyFp other) + { + // Simply "emulates" a 128 bit multiplication. + // However: the resulting number only contains 64 bits. The least + // significant 64 bits are only used for rounding the most significant 64 + // bits. + const long kM32 = 0xFFFFFFFFU; + ulong a = f >> 32; + ulong b = f & kM32; + ulong c = other.f >> 32; + ulong d = other.f & kM32; + ulong ac = a * c; + ulong bc = b * c; + ulong ad = a * d; + ulong bd = b * d; + ulong tmp = (bd >> 32) + (ad & kM32) + (bc & kM32); + // By adding 1U << 31 to tmp we round the final result. + // Halfway cases will be round up. + tmp += 1U << 31; + ulong result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); + e += other.e + 64; + f = result_f; + } + + // returns a * b; + public static DiyFp Times(ref DiyFp a, ref DiyFp b) + { + DiyFp result = a; + result.Multiply(ref b); + return result; + } + + public static DiyFp operator *(DiyFp lhs, DiyFp rhs) + { + return Times(ref lhs, ref rhs); + } + + public void Normalize() + { + ulong significand = f; + int exponent = e; + + // This method is mainly called for normalizing boundaries. In general + // boundaries need to be shifted by 10 bits. We thus optimize for this case. + const ulong k10MSBits = 0xFFC0000000000000; // UINT64_2PART_C(0xFFC00000, 00000000); + while ((significand & k10MSBits) == 0) + { + significand <<= 10; + exponent -= 10; + } + while ((significand & kUint64MSB) == 0) + { + significand <<= 1; + exponent--; + } + f = significand; + e = exponent; + } + + public static DiyFp Normalize(ref DiyFp a) + { + DiyFp result = a; + result.Normalize(); + return result; + } + } +} \ No newline at end of file diff --git a/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs b/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs new file mode 100644 index 00000000..589b966f --- /dev/null +++ b/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs @@ -0,0 +1,890 @@ +using System; +using System.Globalization; + +namespace Cysharp.Text.Internal +{ + using uint64_t = System.UInt64; + using uint32_t = System.UInt32; + using System.Collections.Generic; + using System.Text; + + internal ref struct StringBuilder + { + public Span buffer; + public int offset; + + public StringBuilder(Span buffer) + { + this.buffer = buffer; + this.offset = 0; + } + + public bool TryAddCharacter(char str) + { + if (buffer.Length - offset < 1) return false; + buffer[offset++] = str; + return true; + } + + public bool TryAddCharacter(byte str) + { + if (buffer.Length - offset < 1) return false; + buffer[offset++] = (char)str; + return true; + } + + public bool TryAddString(char[] str) + { + if (buffer.Length - offset < str.Length) return false; + for (int i = 0; i < str.Length; i++) + { + buffer[offset + i] = str[i]; + } + offset += str.Length; + return true; + } + + public bool TryAddSubstring(char[] str, int length) + { + if (buffer.Length - offset < length) return false; + for (int i = 0; i < length; i++) + { + buffer[offset + i] = str[i]; + } + offset += length; + return true; + } + + public bool TryAddSubstring(byte[] str, int length) + { + if (buffer.Length - offset < length) return false; + for (int i = 0; i < length; i++) + { + buffer[offset + i] = (char)str[i]; + } + offset += length; + return true; + } + + public bool TryAddSubstring(char[] str, int start, int length) + { + if (buffer.Length - offset < (length - start)) return false; + for (int i = 0; i < length; i++) + { + buffer[offset + i] = str[start + i]; + } + offset += length; + return true; + } + + public bool TryAddSubstring(byte[] str, int start, int length) + { + if (buffer.Length - offset < (length - start)) return false; + for (int i = 0; i < length; i++) + { + buffer[offset + i] = (char)str[start + i]; + } + offset += length; + return true; + } + + public bool TryAddPadding(char c, int count) + { + if (buffer.Length - offset < count) return false; + for (int i = 0; i < count; i++) + { + buffer[offset + i] = c; + } + offset += count; + return true; + } + + public bool TryAddStringSlow(string str) + { + var s = str.AsSpan(); + if (s.TryCopyTo(buffer.Slice(offset))) + { + offset += s.Length; + return true; + } + return false; + } + } + + // C# API + internal static partial class DoubleToStringConverter + { + public static bool TryFormat(Span destination, float value, out int charsWritten) + { + var sb = new StringBuilder(destination); + if (!ToShortestIeeeNumber(value, ref sb, DtoaMode.SHORTEST_SINGLE)) + { + charsWritten = 0; + return false; + } + + charsWritten = sb.offset; + return true; + } + + public static bool TryFormat(Span destination, double value, out int charsWritten) + { + var sb = new StringBuilder(destination); + if (!ToShortestIeeeNumber(value, ref sb, DtoaMode.SHORTEST)) + { + charsWritten = 0; + return false; + } + + charsWritten = sb.offset; + return true; + } + + [ThreadStatic] + static byte[] exponentialRepBuffer; + + [ThreadStatic] + static byte[] decimalRepBuffer; + + static byte[] GetDecimalRepBuffer(int size) + { + if (decimalRepBuffer == null) + { + decimalRepBuffer = new byte[size]; + } + return decimalRepBuffer; + } + + static byte[] GetExponentialRepBuffer(int size) + { + if (exponentialRepBuffer == null) + { + exponentialRepBuffer = new byte[size]; + } + return exponentialRepBuffer; + } + } + + // private porting methods + // https://github.com/google/double-conversion/blob/master/double-conversion/fast-dtoa.h + // https://github.com/google/double-conversion/blob/master/double-conversion/fast-dtoa.cc + + internal static partial class DoubleToStringConverter + { + enum FastDtoaMode + { + // Computes the shortest representation of the given input. The returned + // result will be the most accurate number of this length. Longer + // representations might be more accurate. + FAST_DTOA_SHORTEST, + // Same as FAST_DTOA_SHORTEST but for single-precision floats. + FAST_DTOA_SHORTEST_SINGLE, + // Computes a representation where the precision (number of digits) is + // given as input. The precision is independent of the decimal point. + // FAST_DTOA_PRECISION + }; + + enum DtoaMode + { + SHORTEST, + SHORTEST_SINGLE, + // FIXED, + // PRECISION + } + + enum Flags + { + NO_FLAGS = 0, + EMIT_POSITIVE_EXPONENT_SIGN = 1, + EMIT_TRAILING_DECIMAL_POINT = 2, + EMIT_TRAILING_ZERO_AFTER_POINT = 4, + UNIQUE_ZERO = 8 + }; + + // C# constants + static readonly char[] infinity_symbol_ = double.PositiveInfinity.ToString().ToCharArray(); + static readonly char[] nan_symbol_ = double.NaN.ToString().ToCharArray(); + + // constructor parameter, same as EcmaScriptConverter + //DoubleToStringConverter(int flags, + // const char* infinity_symbol, + // const char* nan_symbol, + // char exponent_character, + // int decimal_in_shortest_low, + // int decimal_in_shortest_high, + // int max_leading_padding_zeroes_in_precision_mode, + // int max_trailing_padding_zeroes_in_precision_mode) + + //const char exponent_character_; + //const int decimal_in_shortest_low_; + //const int decimal_in_shortest_high_; + //const int max_leading_padding_zeroes_in_precision_mode_; + //const int max_trailing_padding_zeroes_in_precision_mode_; + + static readonly Flags flags_ = Flags.UNIQUE_ZERO | Flags.EMIT_POSITIVE_EXPONENT_SIGN; + static readonly char exponent_character_ = 'E'; + static readonly int decimal_in_shortest_low_ = -4; // C# ToString("G") + static readonly int decimal_in_shortest_high_ = 15;// C# ToString("G") + + const int kBase10MaximalLength = 17; + + const int kFastDtoaMaximalLength = 17; + // Same for single-precision numbers. + const int kFastDtoaMaximalSingleLength = 9; + + // The minimal and maximal target exponent define the range of w's binary + // exponent, where 'w' is the result of multiplying the input by a cached power + // of ten. + // + // A different range might be chosen on a different platform, to optimize digit + // generation, but a smaller range requires more powers of ten to be cached. + const int kMinimalTargetExponent = -60; + const int kMaximalTargetExponent = -32; + + // Adjusts the last digit of the generated number, and screens out generated + // solutions that may be inaccurate. A solution may be inaccurate if it is + // outside the safe interval, or if we cannot prove that it is closer to the + // input than a neighboring representation of the same length. + // + // Input: * buffer containing the digits of too_high / 10^kappa + // * the buffer's length + // * distance_too_high_w == (too_high - w).f() * unit + // * unsafe_interval == (too_high - too_low).f() * unit + // * rest = (too_high - buffer * 10^kappa).f() * unit + // * ten_kappa = 10^kappa * unit + // * unit = the common multiplier + // Output: returns true if the buffer is guaranteed to contain the closest + // representable number to the input. + // Modifies the generated digits in the buffer to approach (round towards) w. + static bool RoundWeed(byte[] buffer, + int length, + uint64_t distance_too_high_w, + uint64_t unsafe_interval, + uint64_t rest, + uint64_t ten_kappa, + uint64_t unit) + { + uint64_t small_distance = distance_too_high_w - unit; + uint64_t big_distance = distance_too_high_w + unit; + // Let w_low = too_high - big_distance, and + // w_high = too_high - small_distance. + // Note: w_low < w < w_high + // + // The real w (* unit) must lie somewhere inside the interval + // ]w_low; w_high[ (often written as "(w_low; w_high)") + + // Basically the buffer currently contains a number in the unsafe interval + // ]too_low; too_high[ with too_low < w < too_high + // + // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ^v 1 unit ^ ^ ^ ^ + // boundary_high --------------------- . . . . + // ^v 1 unit . . . . + // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . + // . . ^ . . + // . big_distance . . . + // . . . . rest + // small_distance . . . . + // v . . . . + // w_high - - - - - - - - - - - - - - - - - - . . . . + // ^v 1 unit . . . . + // w ---------------------------------------- . . . . + // ^v 1 unit v . . . + // w_low - - - - - - - - - - - - - - - - - - - - - . . . + // . . v + // buffer --------------------------------------------------+-------+-------- + // . . + // safe_interval . + // v . + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . + // ^v 1 unit . + // boundary_low ------------------------- unsafe_interval + // ^v 1 unit v + // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // + // Note that the value of buffer could lie anywhere inside the range too_low + // to too_high. + // + // boundary_low, boundary_high and w are approximations of the real boundaries + // and v (the input number). They are guaranteed to be precise up to one unit. + // In fact the error is guaranteed to be strictly less than one unit. + // + // Anything that lies outside the unsafe interval is guaranteed not to round + // to v when read again. + // Anything that lies inside the safe interval is guaranteed to round to v + // when read again. + // If the number inside the buffer lies inside the unsafe interval but not + // inside the safe interval then we simply do not know and bail out (returning + // false). + // + // Similarly we have to take into account the imprecision of 'w' when finding + // the closest representation of 'w'. If we have two potential + // representations, and one is closer to both w_low and w_high, then we know + // it is closer to the actual value v. + // + // By generating the digits of too_high we got the largest (closest to + // too_high) buffer that is still in the unsafe interval. In the case where + // w_high < buffer < too_high we try to decrement the buffer. + // This way the buffer approaches (rounds towards) w. + // There are 3 conditions that stop the decrementation process: + // 1) the buffer is already below w_high + // 2) decrementing the buffer would make it leave the unsafe interval + // 3) decrementing the buffer would yield a number below w_high and farther + // away than the current number. In other words: + // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high + // Instead of using the buffer directly we use its distance to too_high. + // Conceptually rest ~= too_high - buffer + // We need to do the following tests in this order to avoid over- and + // underflows. + while (rest < small_distance && // Negated condition 1 + unsafe_interval - rest >= ten_kappa && // Negated condition 2 + (rest + ten_kappa < small_distance || // buffer{-1} > w_high + small_distance - rest >= rest + ten_kappa - small_distance)) + { + buffer[length - 1]--; + rest += ten_kappa; + } + + // We have approached w+ as much as possible. We now test if approaching w- + // would require changing the buffer. If yes, then we have two possible + // representations close to w, but we cannot decide which one is closer. + if (rest < big_distance && + unsafe_interval - rest >= ten_kappa && + (rest + ten_kappa < big_distance || + big_distance - rest > rest + ten_kappa - big_distance)) + { + return false; + } + + // Weeding test. + // The safe interval is [too_low + 2 ulp; too_high - 2 ulp] + // Since too_low = too_high - unsafe_interval this is equivalent to + // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp] + // Conceptually we have: rest ~= too_high - buffer + return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit); + } + + // Returns the biggest power of ten that is less than or equal to the given + // number. We furthermore receive the maximum number of bits 'number' has. + // + // Returns power == 10^(exponent_plus_one-1) such that + // power <= number < power * 10. + // If number_bits == 0 then 0^(0-1) is returned. + // The number of bits must be <= 32. + // Precondition: number < (1 << (number_bits + 1)). + + // Inspired by the method for finding an integer log base 10 from here: + // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 + static readonly uint[] kSmallPowersOfTen = new uint[] { 0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + + static void BiggestPowerTen(uint32_t number, + int number_bits, + out uint32_t power, + out int exponent_plus_one) + { + // 1233/4096 is approximately 1/lg(10). + int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12); + // We increment to skip over the first entry in the kPowersOf10 table. + // Note: kPowersOf10[i] == 10^(i-1). + exponent_plus_one_guess++; + // We don't have any guarantees that 2^number_bits <= number. + if (number < kSmallPowersOfTen[exponent_plus_one_guess]) + { + exponent_plus_one_guess--; + } + power = kSmallPowersOfTen[exponent_plus_one_guess]; + exponent_plus_one = exponent_plus_one_guess; + } + + // Generates the digits of input number w. + // w is a floating-point number (DiyFp), consisting of a significand and an + // exponent. Its exponent is bounded by kMinimalTargetExponent and + // kMaximalTargetExponent. + // Hence -60 <= w.e() <= -32. + // + // Returns false if it fails, in which case the generated digits in the buffer + // should not be used. + // Preconditions: + // * low, w and high are correct up to 1 ulp (unit in the last place). That + // is, their error must be less than a unit of their last digits. + // * low.e() == w.e() == high.e() + // * low < w < high, and taking into account their error: low~ <= high~ + // * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent + // Postconditions: returns false if procedure fails. + // otherwise: + // * buffer is not null-terminated, but len contains the number of digits. + // * buffer contains the shortest possible decimal digit-sequence + // such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the + // correct values of low and high (without their error). + // * if more than one decimal representation gives the minimal number of + // decimal digits then the one closest to W (where W is the correct value + // of w) is chosen. + // Remark: this procedure takes into account the imprecision of its input + // numbers. If the precision is not enough to guarantee all the postconditions + // then false is returned. This usually happens rarely (~0.5%). + // + // Say, for the sake of example, that + // w.e() == -48, and w.f() == 0x1234567890abcdef + // w's value can be computed by w.f() * 2^w.e() + // We can obtain w's integral digits by simply shifting w.f() by -w.e(). + // -> w's integral part is 0x1234 + // w's fractional part is therefore 0x567890abcdef. + // Printing w's integral part is easy (simply print 0x1234 in decimal). + // In order to print its fraction we repeatedly multiply the fraction by 10 and + // get each digit. Example the first digit after the point would be computed by + // (0x567890abcdef * 10) >> 48. -> 3 + // The whole thing becomes slightly more complicated because we want to stop + // once we have enough digits. That is, once the digits inside the buffer + // represent 'w' we can stop. Everything inside the interval low - high + // represents w. However we have to pay attention to low, high and w's + // imprecision. + static bool DigitGen(DiyFp low, + DiyFp w, + DiyFp high, + byte[] buffer, + out int length, + out int kappa) + { + // low, w and high are imprecise, but by less than one ulp (unit in the last + // place). + // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that + // the new numbers are outside of the interval we want the final + // representation to lie in. + // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield + // numbers that are certain to lie in the interval. We will use this fact + // later on. + // We will now start by generating the digits within the uncertain + // interval. Later we will weed out representations that lie outside the safe + // interval and thus _might_ lie outside the correct interval. + uint64_t unit = 1; + DiyFp too_low = new DiyFp(low.f - unit, low.e); + DiyFp too_high = new DiyFp(high.f + unit, high.e); + // too_low and too_high are guaranteed to lie outside the interval we want the + // generated number in. + DiyFp unsafe_interval = DiyFp.Minus(ref too_high, ref too_low); + // We now cut the input number into two parts: the integral digits and the + // fractionals. We will not write any decimal separator though, but adapt + // kappa instead. + // Reminder: we are currently computing the digits (stored inside the buffer) + // such that: too_low < buffer * 10^kappa < too_high + // We use too_high for the digit_generation and stop as soon as possible. + // If we stop early we effectively round down. + DiyFp one = new DiyFp((uint64_t)(1) << -w.e, w.e); + // Division by one is a shift. + uint32_t integrals = (uint32_t)(too_high.f >> -one.e); + // Modulo by one is an and. + uint64_t fractionals = too_high.f & (one.f - 1); + uint32_t divisor; + int divisor_exponent_plus_one; + BiggestPowerTen(integrals, DiyFp.kSignificandSize - (-one.e), + out divisor, out divisor_exponent_plus_one); + kappa = divisor_exponent_plus_one; + length = 0; + // Loop invariant: buffer = too_high / 10^kappa (integer division) + // The invariant holds for the first iteration: kappa has been initialized + // with the divisor exponent + 1. And the divisor is the biggest power of ten + // that is smaller than integrals. + while (kappa > 0) + { + int digit = unchecked((int)(integrals / divisor)); + buffer[length] = (byte)((byte)'0' + digit); + (length)++; + integrals %= divisor; + (kappa)--; + // Note that kappa now equals the exponent of the divisor and that the + // invariant thus holds again. + uint64_t rest = + ((uint64_t)(integrals) << -one.e) + fractionals; + // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e()) + // Reminder: unsafe_interval.e() == one.e() + if (rest < unsafe_interval.f) + { + // Rounding down (by not emitting the remaining digits) yields a number + // that lies within the unsafe interval. + return RoundWeed(buffer, length, DiyFp.Minus(ref too_high, ref w).f, + unsafe_interval.f, rest, + (uint64_t)(divisor) << -one.e, unit); + } + divisor /= 10; + } + + // The integrals have been generated. We are at the point of the decimal + // separator. In the following loop we simply multiply the remaining digits by + // 10 and divide by one. We just need to pay attention to multiply associated + // data (like the interval or 'unit'), too. + // Note that the multiplication by 10 does not overflow, because w.e >= -60 + // and thus one.e >= -60. + for (; ; ) + { + fractionals *= 10; + unit *= 10; + unsafe_interval.f = (unsafe_interval.f * 10); + // Integer division by one. + int digit = (int)(fractionals >> -one.e); + buffer[length] = (byte)((byte)'0' + digit); + (length)++; + fractionals &= one.f - 1; // Modulo by one. + (kappa)--; + if (fractionals < unsafe_interval.f) + { + return RoundWeed(buffer, length, DiyFp.Minus(ref too_high, ref w).f * unit, + unsafe_interval.f, fractionals, one.f, unit); + } + } + } + + // Provides a decimal representation of v. + // Returns true if it succeeds, otherwise the result cannot be trusted. + // There will be *length digits inside the buffer (not null-terminated). + // If the function returns true then + // v == (double) (buffer * 10^decimal_exponent). + // The digits in the buffer are the shortest representation possible: no + // 0.09999999999999999 instead of 0.1. The shorter representation will even be + // chosen even if the longer one would be closer to v. + // The last digit will be closest to the actual v. That is, even if several + // digits might correctly yield 'v' when read again, the closest will be + // computed. + static bool Grisu3(double v, + FastDtoaMode mode, + byte[] buffer, + out int length, + out int decimal_exponent) + { + DiyFp w = new Double(v).AsNormalizedDiyFp(); + // boundary_minus and boundary_plus are the boundaries between v and its + // closest floating-point neighbors. Any number strictly between + // boundary_minus and boundary_plus will round to v when convert to a double. + // Grisu3 will never output representations that lie exactly on a boundary. + DiyFp boundary_minus, boundary_plus; + if (mode == FastDtoaMode.FAST_DTOA_SHORTEST) + { + new Double(v).NormalizedBoundaries(out boundary_minus, out boundary_plus); + } + else if (mode == FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE) + { + float single_v = (float)(v); + new Single(single_v).NormalizedBoundaries(out boundary_minus, out boundary_plus); + } + else + { + throw new Exception("Invalid Mode."); + } + + DiyFp ten_mk; // Cached power of ten: 10^-k + int mk; // -k + int ten_mk_minimal_binary_exponent = + kMinimalTargetExponent - (w.e + DiyFp.kSignificandSize); + int ten_mk_maximal_binary_exponent = + kMaximalTargetExponent - (w.e + DiyFp.kSignificandSize); + PowersOfTenCache.GetCachedPowerForBinaryExponentRange( + ten_mk_minimal_binary_exponent, + ten_mk_maximal_binary_exponent, + out ten_mk, out mk); + + // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a + // 64 bit significand and ten_mk is thus only precise up to 64 bits. + + // The DiyFp::Times procedure rounds its result, and ten_mk is approximated + // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now + // off by a small amount. + // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. + // In other words: let f = scaled_w.f() and e = scaled_w.e(), then + // (f-1) * 2^e < w*10^k < (f+1) * 2^e + DiyFp scaled_w = DiyFp.Times(ref w, ref ten_mk); + + // In theory it would be possible to avoid some recomputations by computing + // the difference between w and boundary_minus/plus (a power of 2) and to + // compute scaled_boundary_minus/plus by subtracting/adding from + // scaled_w. However the code becomes much less readable and the speed + // enhancements are not terriffic. + DiyFp scaled_boundary_minus = DiyFp.Times(ref boundary_minus, ref ten_mk); + DiyFp scaled_boundary_plus = DiyFp.Times(ref boundary_plus, ref ten_mk); + + // DigitGen will generate the digits of scaled_w. Therefore we have + // v == (double) (scaled_w * 10^-mk). + // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an + // integer than it will be updated. For instance if scaled_w == 1.23 then + // the buffer will be filled with "123" und the decimal_exponent will be + // decreased by 2. + int kappa; + bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, + buffer, out length, out kappa); + decimal_exponent = -mk + kappa; + return result; + } + + static bool FastDtoa(double v, + FastDtoaMode mode, + // int requested_digits, + byte[] buffer, + out int length, + out int decimal_point) + { + bool result = false; + int decimal_exponent = 0; + switch (mode) + { + case FastDtoaMode.FAST_DTOA_SHORTEST: + case FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE: + result = Grisu3(v, mode, buffer, out length, out decimal_exponent); + break; + // case FastDtoaMode.FAST_DTOA_PRECISION: + //result = Grisu3Counted(v, requested_digits, buffer, length, &decimal_exponent); + default: + throw new Exception("unreachable code."); + } + if (result) + { + decimal_point = length + decimal_exponent; + } + else + { + decimal_point = -1; + } + return result; + } + + // https://github.com/google/double-conversion/blob/master/double-conversion/double-conversion.cc + + static bool HandleSpecialValues( + double value, + ref StringBuilder result_builder) + { + Double double_inspect = new Double(value); + if (double_inspect.IsInfinite()) + { + if (infinity_symbol_ == null) return false; + if (value < 0) + { + if (!result_builder.TryAddCharacter('-')) return false; + } + if (!result_builder.TryAddString(infinity_symbol_)) return false; + return true; + } + if (double_inspect.IsNan()) + { + if (nan_symbol_ == null) return false; + if (!result_builder.TryAddString(nan_symbol_)) return false; + return true; + } + return false; + } + + static bool ToShortestIeeeNumber( + double value, + ref StringBuilder result_builder, + DtoaMode mode) + { + if (new Double(value).IsSpecial()) + { + return HandleSpecialValues(value, ref result_builder); + } + + int decimal_point; + bool sign; + const int kDecimalRepCapacity = kBase10MaximalLength + 1; + var decimal_rep = GetDecimalRepBuffer(kDecimalRepCapacity); // byte[] decimal_rep = new byte[kDecimalRepCapacity]; + int decimal_rep_length; + + var fastworked = DoubleToAscii(value, mode, 0, decimal_rep, + out sign, out decimal_rep_length, out decimal_point); + + if (!fastworked) + { + // C# custom, slow path + var str = value.ToString("G17", CultureInfo.InvariantCulture); + if (!result_builder.TryAddStringSlow(str)) return false; + return true; + } + + bool unique_zero = (flags_ & Flags.UNIQUE_ZERO) != 0; + if (sign && (value != 0.0 || !unique_zero)) + { + if (!result_builder.TryAddCharacter('-')) return false; + } + + int exponent = decimal_point - 1; + if ((decimal_in_shortest_low_ <= exponent) && + (exponent < decimal_in_shortest_high_)) + { + return CreateDecimalRepresentation(decimal_rep, decimal_rep_length, + decimal_point, + Math.Max(0, decimal_rep_length - decimal_point), + ref result_builder); + } + else + { + return CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, + ref result_builder); + } + } + + static bool CreateDecimalRepresentation( + byte[] decimal_digits, + int length, + int decimal_point, + int digits_after_point, + ref StringBuilder result_builder) + { + // Create a representation that is padded with zeros if needed. + if (decimal_point <= 0) + { + // "0.00000decimal_rep" or "0.000decimal_rep00". + if (!result_builder.TryAddCharacter('0')) return false; + if (digits_after_point > 0) + { + if (!result_builder.TryAddCharacter('.')) return false; + if (!result_builder.TryAddPadding('0', -decimal_point)) return false; + if (!result_builder.TryAddSubstring(decimal_digits, length)) return false; + int remaining_digits = digits_after_point - (-decimal_point) - length; + if (!result_builder.TryAddPadding('0', remaining_digits)) return false; + } + } + else if (decimal_point >= length) + { + // "decimal_rep0000.00000" or "decimal_rep.0000". + if (!result_builder.TryAddSubstring(decimal_digits, length)) return false; + if (!result_builder.TryAddPadding('0', decimal_point - length)) return false; + if (digits_after_point > 0) + { + if (!result_builder.TryAddCharacter('.')) return false; + if (!result_builder.TryAddPadding('0', digits_after_point)) return false; + } + } + else + { + // "decima.l_rep000". + if (!result_builder.TryAddSubstring(decimal_digits, decimal_point)) return false; + if (!result_builder.TryAddCharacter('.')) return false; + if (!result_builder.TryAddSubstring(decimal_digits, decimal_point, length - decimal_point)) return false; + int remaining_digits = digits_after_point - (length - decimal_point); + if (!result_builder.TryAddPadding('0', remaining_digits)) return false; + } + if (digits_after_point == 0) + { + if ((flags_ & Flags.EMIT_TRAILING_DECIMAL_POINT) != 0) + { + if (!result_builder.TryAddCharacter('.')) return false; + } + if ((flags_ & Flags.EMIT_TRAILING_ZERO_AFTER_POINT) != 0) + { + if (!result_builder.TryAddCharacter('0')) return false; + } + } + + return true; + } + + static bool CreateExponentialRepresentation( + byte[] decimal_digits, + int length, + int exponent, + ref StringBuilder result_builder) + { + if (!result_builder.TryAddCharacter(decimal_digits[0])) return false; + if (length != 1) + { + if (!result_builder.TryAddCharacter('.')) return false; + if (!result_builder.TryAddSubstring(decimal_digits, 1, length - 1)) return false; + } + if (!result_builder.TryAddCharacter(exponent_character_)) return false; + if (exponent < 0) + { + if (!result_builder.TryAddCharacter('-')) return false; + exponent = -exponent; + } + else + { + if ((flags_ & Flags.EMIT_POSITIVE_EXPONENT_SIGN) != 0) + { + if (!result_builder.TryAddCharacter('+')) return false; + } + } + if (exponent == 0) + { + if (!result_builder.TryAddCharacter('0')) return false; + return true; + } + const int kMaxExponentLength = 5; + byte[] buffer = GetExponentialRepBuffer(kMaxExponentLength + 1); + buffer[kMaxExponentLength] = (byte)'\0'; + int first_char_pos = kMaxExponentLength; + while (exponent > 0) + { + buffer[--first_char_pos] = (byte)((byte)'0' + (exponent % 10)); + exponent /= 10; + } + if (!result_builder.TryAddSubstring(buffer, first_char_pos, kMaxExponentLength - first_char_pos)) return false; + + return true; + } + + // modified, return fast_worked. + static bool DoubleToAscii(double v, + DtoaMode mode, + int requested_digits, + //byte[] buffer, + //int buffer_length, + byte[] vector, // already allocate + out bool sign, + out int length, + out int point) + { + if (new Double(v).Sign() < 0) + { + sign = true; + v = -v; + } + else + { + sign = false; + } + + //if (mode == DtoaMode.PRECISION && requested_digits == 0) + //{ + // vector[0] = '\0'; + // *length = 0; + // return; + //} + + if (v == 0) + { + vector[0] = (byte)'0'; + // vector[1] = '\0'; + length = 1; + point = 1; + return true; + } + + bool fast_worked; + switch (mode) + { + case DtoaMode.SHORTEST: + fast_worked = FastDtoa(v, FastDtoaMode.FAST_DTOA_SHORTEST, vector, out length, out point); + break; + case DtoaMode.SHORTEST_SINGLE: + fast_worked = FastDtoa(v, FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE, vector, out length, out point); + break; + //case FIXED: + // fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); + // break; + //case PRECISION: + // fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, + // vector, length, point); + // break; + default: + fast_worked = false; + throw new Exception("Unreachable code."); + } + // if (fast_worked) return; + + // If the fast dtoa didn't succeed use the slower bignum version. + // BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); + // BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); + // vector[*length] = '\0'; + + return fast_worked; + } + } +} \ No newline at end of file diff --git a/src/ZString/Shims/DoubleConversion/IEEE.cs b/src/ZString/Shims/DoubleConversion/IEEE.cs new file mode 100644 index 00000000..55bc2fc3 --- /dev/null +++ b/src/ZString/Shims/DoubleConversion/IEEE.cs @@ -0,0 +1,441 @@ +using System; +using System.Runtime.InteropServices; + +namespace Cysharp.Text.Internal +{ + using uint32_t = UInt32; + + [StructLayout(LayoutKind.Explicit, Pack = 1)] + internal struct UnionDoubleULong + { + [FieldOffset(0)] + public double d; + [FieldOffset(0)] + public ulong u64; + } + + [StructLayout(LayoutKind.Explicit, Pack = 1)] + internal struct UnionFloatUInt + { + [FieldOffset(0)] + public float f; + [FieldOffset(0)] + public uint u32; + } + + // https://github.com/google/double-conversion/blob/master/double-conversion/ieee.h + + internal struct Double + { + public const ulong kSignMask = (0x8000000000000000); + public const ulong kExponentMask = (0x7FF0000000000000); + public const ulong kSignificandMask = (0x000FFFFFFFFFFFFF); + public const ulong kHiddenBit = (0x0010000000000000); + public const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. + public const int kSignificandSize = 53; + + const int kExponentBias = 0x3FF + kPhysicalSignificandSize; + const int kDenormalExponent = -kExponentBias + 1; + const int kMaxExponent = 0x7FF - kExponentBias; + const ulong kInfinity = (0x7FF0000000000000); + const ulong kNaN = (0x7FF8000000000000); + + ulong d64_; + + public Double(double d) + { + d64_ = new UnionDoubleULong { d = d }.u64; + } + + public Double(DiyFp d) + { + d64_ = DiyFpToUint64(d); + } + + // The value encoded by this Double must be greater or equal to +0.0. + // It must not be special (infinity, or NaN). + public DiyFp AsDiyFp() + { + return new DiyFp(Significand(), Exponent()); + } + + // The value encoded by this Double must be strictly greater than 0. + public DiyFp AsNormalizedDiyFp() + { + ulong f = Significand(); + int e = Exponent(); + + // The current double could be a denormal. + while ((f & kHiddenBit) == 0) + { + f <<= 1; + e--; + } + // Do the final shifts in one go. + f <<= DiyFp.kSignificandSize - kSignificandSize; + e -= DiyFp.kSignificandSize - kSignificandSize; + return new DiyFp(f, e); + } + + // Returns the double's bit as uint64. + public ulong AsUint64() + { + return d64_; + } + + // Returns the next greater double. Returns +infinity on input +infinity. + public double NextDouble() + { + if (d64_ == kInfinity) return new Double(kInfinity).value(); + if (Sign() < 0 && Significand() == 0) + { + // -0.0 + return 0.0; + } + if (Sign() < 0) + { + return new Double(d64_ - 1).value(); + } + else + { + return new Double(d64_ + 1).value(); + } + } + + public double PreviousDouble() + { + if (d64_ == (kInfinity | kSignMask)) return -Infinity(); + if (Sign() < 0) + { + return new Double(d64_ + 1).value(); + } + else + { + if (Significand() == 0) return -0.0; + return new Double(d64_ - 1).value(); + } + } + + public int Exponent() + { + if (IsDenormal()) return kDenormalExponent; + + ulong d64 = AsUint64(); + int biased_e = + (int)((d64 & kExponentMask) >> kPhysicalSignificandSize); + return biased_e - kExponentBias; + } + + public ulong Significand() + { + ulong d64 = AsUint64(); + ulong significand = d64 & kSignificandMask; + if (!IsDenormal()) + { + return significand + kHiddenBit; + } + else + { + return significand; + } + } + + // Returns true if the double is a denormal. + public bool IsDenormal() + { + ulong d64 = AsUint64(); + return (d64 & kExponentMask) == 0; + } + + // We consider denormals not to be special. + // Hence only Infinity and NaN are special. + public bool IsSpecial() + { + ulong d64 = AsUint64(); + return (d64 & kExponentMask) == kExponentMask; + } + + public bool IsNan() + { + ulong d64 = AsUint64(); + return ((d64 & kExponentMask) == kExponentMask) && + ((d64 & kSignificandMask) != 0); + } + + public bool IsInfinite() + { + ulong d64 = AsUint64(); + return ((d64 & kExponentMask) == kExponentMask) && + ((d64 & kSignificandMask) == 0); + } + + public int Sign() + { + ulong d64 = AsUint64(); + return (d64 & kSignMask) == 0 ? 1 : -1; + } + + // Precondition: the value encoded by this Double must be greater or equal + // than +0.0. + public DiyFp UpperBoundary() + { + return new DiyFp(Significand() * 2 + 1, Exponent() - 1); + } + + // Computes the two boundaries of this. + // The bigger boundary (m_plus) is normalized. The lower boundary has the same + // exponent as m_plus. + // Precondition: the value encoded by this Double must be greater than 0. + public void NormalizedBoundaries(out DiyFp out_m_minus, out DiyFp out_m_plus) + { + DiyFp v = this.AsDiyFp(); + var __ = new DiyFp((v.f << 1) + 1, v.e - 1); + var m_plus = DiyFp.Normalize(ref __); + + DiyFp m_minus; + if (LowerBoundaryIsCloser()) + { + m_minus = new DiyFp((v.f << 2) - 1, v.e - 2); + } + else + { + m_minus = new DiyFp((v.f << 1) - 1, v.e - 1); + } + m_minus.f = m_minus.f << (m_minus.e - m_plus.e); + m_minus.e = (m_plus.e); + out_m_plus = m_plus; + out_m_minus = m_minus; + } + + public bool LowerBoundaryIsCloser() + { + // The boundary is closer if the significand is of the form f == 2^p-1 then + // the lower boundary is closer. + // Think of v = 1000e10 and v- = 9999e9. + // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but + // at a distance of 1e8. + // The only exception is for the smallest normal: the largest denormal is + // at the same distance as its successor. + // Note: denormals have the same exponent as the smallest normals. + bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0); + return physical_significand_is_zero && (Exponent() != kDenormalExponent); + } + + public double value() + { + return new UnionDoubleULong { u64 = d64_ }.d; + } + + // Returns the significand size for a given order of magnitude. + // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude. + // This function returns the number of significant binary digits v will have + // once it's encoded into a double. In almost all cases this is equal to + // kSignificandSize. The only exceptions are denormals. They start with + // leading zeroes and their effective significand-size is hence smaller. + public static int SignificandSizeForOrderOfMagnitude(int order) + { + if (order >= (kDenormalExponent + kSignificandSize)) + { + return kSignificandSize; + } + if (order <= kDenormalExponent) return 0; + return order - kDenormalExponent; + } + + public static double Infinity() + { + return new Double(kInfinity).value(); + } + + public static double NaN() + { + return new Double(kNaN).value(); + } + + public static ulong DiyFpToUint64(DiyFp diy_fp) + { + ulong significand = diy_fp.f; + int exponent = diy_fp.e; + while (significand > kHiddenBit + kSignificandMask) + { + significand >>= 1; + exponent++; + } + if (exponent >= kMaxExponent) + { + return kInfinity; + } + if (exponent < kDenormalExponent) + { + return 0; + } + while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) + { + significand <<= 1; + exponent--; + } + ulong biased_exponent; + if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) + { + biased_exponent = 0; + } + else + { + biased_exponent = (ulong)(exponent + kExponentBias); + } + return (significand & kSignificandMask) | + (biased_exponent << kPhysicalSignificandSize); + } + } + + internal struct Single + { + const int kExponentBias = 0x7F + kPhysicalSignificandSize; + const int kDenormalExponent = -kExponentBias + 1; + const int kMaxExponent = 0xFF - kExponentBias; + const uint32_t kInfinity = 0x7F800000; + const uint32_t kNaN = 0x7FC00000; + + public const uint32_t kSignMask = 0x80000000; + public const uint32_t kExponentMask = 0x7F800000; + public const uint32_t kSignificandMask = 0x007FFFFF; + public const uint32_t kHiddenBit = 0x00800000; + public const int kPhysicalSignificandSize = 23; // Excludes the hidden bit. + public const int kSignificandSize = 24; + + uint32_t d32_; + + public Single(float f) + { + this.d32_ = new UnionFloatUInt { f = f }.u32; + } + + // The value encoded by this Single must be greater or equal to +0.0. + // It must not be special (infinity, or NaN). + public DiyFp AsDiyFp() + { + return new DiyFp(Significand(), Exponent()); + } + + // Returns the single's bit as uint64. + public uint32_t AsUint32() + { + return d32_; + } + + public int Exponent() + { + if (IsDenormal()) return kDenormalExponent; + + uint32_t d32 = AsUint32(); + int biased_e = (int)((d32 & kExponentMask) >> kPhysicalSignificandSize); + return biased_e - kExponentBias; + } + + public uint32_t Significand() + { + uint32_t d32 = AsUint32(); + uint32_t significand = d32 & kSignificandMask; + if (!IsDenormal()) + { + return significand + kHiddenBit; + } + else + { + return significand; + } + } + + // Returns true if the single is a denormal. + public bool IsDenormal() + { + uint32_t d32 = AsUint32(); + return (d32 & kExponentMask) == 0; + } + + // We consider denormals not to be special. + // Hence only Infinity and NaN are special. + public bool IsSpecial() + { + uint32_t d32 = AsUint32(); + return (d32 & kExponentMask) == kExponentMask; + } + + public bool IsNan() + { + uint32_t d32 = AsUint32(); + return ((d32 & kExponentMask) == kExponentMask) && + ((d32 & kSignificandMask) != 0); + } + + public bool IsInfinite() + { + uint32_t d32 = AsUint32(); + return ((d32 & kExponentMask) == kExponentMask) && + ((d32 & kSignificandMask) == 0); + } + + public int Sign() + { + uint32_t d32 = AsUint32(); + return (d32 & kSignMask) == 0 ? 1 : -1; + } + + // Computes the two boundaries of this. + // The bigger boundary (m_plus) is normalized. The lower boundary has the same + // exponent as m_plus. + // Precondition: the value encoded by this Single must be greater than 0. + public void NormalizedBoundaries(out DiyFp out_m_minus, out DiyFp out_m_plus) + { + DiyFp v = this.AsDiyFp(); + var __ = new DiyFp((v.f << 1) + 1, v.e - 1); + DiyFp m_plus = DiyFp.Normalize(ref __); + DiyFp m_minus; + if (LowerBoundaryIsCloser()) + { + m_minus = new DiyFp((v.f << 2) - 1, v.e - 2); + } + else + { + m_minus = new DiyFp((v.f << 1) - 1, v.e - 1); + } + m_minus.f = (m_minus.f << (m_minus.e - m_plus.e)); + m_minus.e = (m_plus.e); + out_m_plus = m_plus; + out_m_minus = m_minus; + } + + // Precondition: the value encoded by this Single must be greater or equal + // than +0.0. + public DiyFp UpperBoundary() + { + return new DiyFp(Significand() * 2 + 1, Exponent() - 1); + } + + public bool LowerBoundaryIsCloser() + { + // The boundary is closer if the significand is of the form f == 2^p-1 then + // the lower boundary is closer. + // Think of v = 1000e10 and v- = 9999e9. + // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but + // at a distance of 1e8. + // The only exception is for the smallest normal: the largest denormal is + // at the same distance as its successor. + // Note: denormals have the same exponent as the smallest normals. + bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0); + return physical_significand_is_zero && (Exponent() != kDenormalExponent); + } + + public float value() { return new UnionFloatUInt { u32 = d32_ }.f; } + + public static float Infinity() + { + return new Single(kInfinity).value(); + } + + public static float NaN() + { + return new Single(kNaN).value(); + } + } +} diff --git a/src/ZString/Shims/DoubleConversion/PowersOfTenCache.cs b/src/ZString/Shims/DoubleConversion/PowersOfTenCache.cs new file mode 100644 index 00000000..2150d858 --- /dev/null +++ b/src/ZString/Shims/DoubleConversion/PowersOfTenCache.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text.Internal +{ + using uint64_t = UInt64; + using int16_t = Int16; + + // https://github.com/google/double-conversion/blob/master/double-conversion/cached-powers.h + // https://github.com/google/double-conversion/blob/master/double-conversion/cached-powers.cc + + internal struct CachedPower + { + public readonly uint64_t significand; + public readonly int16_t binary_exponent; + public readonly int16_t decimal_exponent; + + public CachedPower(ulong significand, short binary_exponent, short decimal_exponent) + { + this.significand = significand; + this.binary_exponent = binary_exponent; + this.decimal_exponent = decimal_exponent; + } + }; + + internal static class PowersOfTenCache + { + static readonly CachedPower[] kCachedPowers = new CachedPower[] + { + new CachedPower (0xfa8fd5a0081c0288, -1220, -348), + new CachedPower (0xbaaee17fa23ebf76, -1193, -340), + new CachedPower (0x8b16fb203055ac76, -1166, -332), + new CachedPower (0xcf42894a5dce35ea, -1140, -324), + new CachedPower (0x9a6bb0aa55653b2d, -1113, -316), + new CachedPower (0xe61acf033d1a45df, -1087, -308), + new CachedPower (0xab70fe17c79ac6ca, -1060, -300), + new CachedPower (0xff77b1fcbebcdc4f, -1034, -292), + new CachedPower (0xbe5691ef416bd60c, -1007, -284), + new CachedPower (0x8dd01fad907ffc3c, -980, -276), + new CachedPower (0xd3515c2831559a83, -954, -268), + new CachedPower (0x9d71ac8fada6c9b5, -927, -260), + new CachedPower (0xea9c227723ee8bcb, -901, -252), + new CachedPower (0xaecc49914078536d, -874, -244), + new CachedPower (0x823c12795db6ce57, -847, -236), + new CachedPower (0xc21094364dfb5637, -821, -228), + new CachedPower (0x9096ea6f3848984f, -794, -220), + new CachedPower (0xd77485cb25823ac7, -768, -212), + new CachedPower (0xa086cfcd97bf97f4, -741, -204), + new CachedPower (0xef340a98172aace5, -715, -196), + new CachedPower (0xb23867fb2a35b28e, -688, -188), + new CachedPower (0x84c8d4dfd2c63f3b, -661, -180), + new CachedPower (0xc5dd44271ad3cdba, -635, -172), + new CachedPower (0x936b9fcebb25c996, -608, -164), + new CachedPower (0xdbac6c247d62a584, -582, -156), + new CachedPower (0xa3ab66580d5fdaf6, -555, -148), + new CachedPower (0xf3e2f893dec3f126, -529, -140), + new CachedPower (0xb5b5ada8aaff80b8, -502, -132), + new CachedPower (0x87625f056c7c4a8b, -475, -124), + new CachedPower (0xc9bcff6034c13053, -449, -116), + new CachedPower (0x964e858c91ba2655, -422, -108), + new CachedPower (0xdff9772470297ebd, -396, -100), + new CachedPower (0xa6dfbd9fb8e5b88f, -369, -92), + new CachedPower (0xf8a95fcf88747d94, -343, -84), + new CachedPower (0xb94470938fa89bcf, -316, -76), + new CachedPower (0x8a08f0f8bf0f156b, -289, -68), + new CachedPower (0xcdb02555653131b6, -263, -60), + new CachedPower (0x993fe2c6d07b7fac, -236, -52), + new CachedPower (0xe45c10c42a2b3b06, -210, -44), + new CachedPower (0xaa242499697392d3, -183, -36), + new CachedPower (0xfd87b5f28300ca0e, -157, -28), + new CachedPower (0xbce5086492111aeb, -130, -20), + new CachedPower (0x8cbccc096f5088cc, -103, -12), + new CachedPower (0xd1b71758e219652c, -77, -4), + new CachedPower (0x9c40000000000000, -50, 4), + new CachedPower (0xe8d4a51000000000, -24, 12), + new CachedPower (0xad78ebc5ac620000, 3, 20), + new CachedPower (0x813f3978f8940984, 30, 28), + new CachedPower (0xc097ce7bc90715b3, 56, 36), + new CachedPower (0x8f7e32ce7bea5c70, 83, 44), + new CachedPower (0xd5d238a4abe98068, 109, 52), + new CachedPower (0x9f4f2726179a2245, 136, 60), + new CachedPower (0xed63a231d4c4fb27, 162, 68), + new CachedPower (0xb0de65388cc8ada8, 189, 76), + new CachedPower (0x83c7088e1aab65db, 216, 84), + new CachedPower (0xc45d1df942711d9a, 242, 92), + new CachedPower (0x924d692ca61be758, 269, 100), + new CachedPower (0xda01ee641a708dea, 295, 108), + new CachedPower (0xa26da3999aef774a, 322, 116), + new CachedPower (0xf209787bb47d6b85, 348, 124), + new CachedPower (0xb454e4a179dd1877, 375, 132), + new CachedPower (0x865b86925b9bc5c2, 402, 140), + new CachedPower (0xc83553c5c8965d3d, 428, 148), + new CachedPower (0x952ab45cfa97a0b3, 455, 156), + new CachedPower (0xde469fbd99a05fe3, 481, 164), + new CachedPower (0xa59bc234db398c25, 508, 172), + new CachedPower (0xf6c69a72a3989f5c, 534, 180), + new CachedPower (0xb7dcbf5354e9bece, 561, 188), + new CachedPower (0x88fcf317f22241e2, 588, 196), + new CachedPower (0xcc20ce9bd35c78a5, 614, 204), + new CachedPower (0x98165af37b2153df, 641, 212), + new CachedPower (0xe2a0b5dc971f303a, 667, 220), + new CachedPower (0xa8d9d1535ce3b396, 694, 228), + new CachedPower (0xfb9b7cd9a4a7443c, 720, 236), + new CachedPower (0xbb764c4ca7a44410, 747, 244), + new CachedPower (0x8bab8eefb6409c1a, 774, 252), + new CachedPower (0xd01fef10a657842c, 800, 260), + new CachedPower (0x9b10a4e5e9913129, 827, 268), + new CachedPower (0xe7109bfba19c0c9d, 853, 276), + new CachedPower (0xac2820d9623bf429, 880, 284), + new CachedPower (0x80444b5e7aa7cf85, 907, 292), + new CachedPower (0xbf21e44003acdd2d, 933, 300), + new CachedPower (0x8e679c2f5e44ff8f, 960, 308), + new CachedPower (0xd433179d9c8cb841, 986, 316), + new CachedPower (0x9e19db92b4e31ba9, 1013, 324), + new CachedPower (0xeb96bf6ebadf77d9, 1039, 332), + new CachedPower (0xaf87023b9bf0ee6b, 1066, 340), + }; + + public const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent. + public const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) + // Difference between the decimal exponents in the table above. + public const int kDecimalExponentDistance = 8; + public const int kMinDecimalExponent = -348; + public const int kMaxDecimalExponent = 340; + + public static void GetCachedPowerForBinaryExponentRange( + int min_exponent, + int max_exponent, + out DiyFp power, + out int decimal_exponent) + { + int kQ = DiyFp.kSignificandSize; + double k = Math.Ceiling((min_exponent + kQ - 1) * kD_1_LOG2_10); + int foo = kCachedPowersOffset; + int index = (foo + (int)(k) - 1) / kDecimalExponentDistance + 1; + + CachedPower cached_power = kCachedPowers[index]; + // (void)max_exponent; // Mark variable as used. + decimal_exponent = cached_power.decimal_exponent; + power = new DiyFp(cached_power.significand, cached_power.binary_exponent); + } + + public static void GetCachedPowerForDecimalExponent(int requested_exponent, + out DiyFp power, + out int found_exponent) + { + int index = (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance; + CachedPower cached_power = kCachedPowers[index]; + power = new DiyFp(cached_power.significand, cached_power.binary_exponent); + found_exponent = cached_power.decimal_exponent; + } + } +} diff --git a/src/ZString/Shims/DoubleConversion/StringToDouble.cs b/src/ZString/Shims/DoubleConversion/StringToDouble.cs new file mode 100644 index 00000000..0c65eb55 --- /dev/null +++ b/src/ZString/Shims/DoubleConversion/StringToDouble.cs @@ -0,0 +1,535 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text.Internal +{ + using uint64_t = UInt64; + + internal struct Vector + { + public readonly byte[] bytes; + public readonly int start; + public readonly int _length; + + public Vector(byte[] bytes, int start, int length) + { + this.bytes = bytes; + this.start = start; + this._length = length; + } + + public byte this[int i] + { + get + { + return bytes[start + i]; + } + set + { + bytes[start + i] = value; + } + } + + public int length() + { + return _length; + } + + public byte first() + { + return bytes[start]; + } + + public byte last() + { + return bytes[_length - 1]; + } + + public bool is_empty() + { + return _length == 0; + } + + public Vector SubVector(int from, int to) + { + return new Vector(this.bytes, start + from, to - from); + } + } + + internal static class StringToDouble + { + [ThreadStatic] + static byte[] copyBuffer; + + static byte[] GetCopyBuffer() + { + if (copyBuffer == null) + { + copyBuffer = new byte[kMaxSignificantDecimalDigits]; + } + return copyBuffer; + } + + // 2^53 = 9007199254740992. + // Any integer with at most 15 decimal digits will hence fit into a double + // (which has a 53bit significand) without loss of precision. + const int kMaxExactDoubleIntegerDecimalDigits = 15; + // 2^64 = 18446744073709551616 > 10^19 + const int kMaxUint64DecimalDigits = 19; + + // Max double: 1.7976931348623157 x 10^308 + // Min non-zero double: 4.9406564584124654 x 10^-324 + // Any x >= 10^309 is interpreted as +infinity. + // Any x <= 10^-324 is interpreted as 0. + // Note that 2.5e-324 (despite being smaller than the min double) will be read + // as non-zero (equal to the min non-zero double). + const int kMaxDecimalPower = 309; + const int kMinDecimalPower = -324; + + // 2^64 = 18446744073709551616 + const uint64_t kMaxUint64 = 0xFFFFFFFFFFFFFFFF; + + static readonly double[] exact_powers_of_ten = new double[]{ + 1.0, // 10^0 + 10.0, + 100.0, + 1000.0, + 10000.0, + 100000.0, + 1000000.0, + 10000000.0, + 100000000.0, + 1000000000.0, + 10000000000.0, // 10^10 + 100000000000.0, + 1000000000000.0, + 10000000000000.0, + 100000000000000.0, + 1000000000000000.0, + 10000000000000000.0, + 100000000000000000.0, + 1000000000000000000.0, + 10000000000000000000.0, + 100000000000000000000.0, // 10^20 + 1000000000000000000000.0, + // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22 + 10000000000000000000000.0 + }; + static readonly int kExactPowersOfTenSize = exact_powers_of_ten.Length; + + // Maximum number of significant digits in the decimal representation. + // In fact the value is 772 (see conversions.cc), but to give us some margin + // we round up to 780. + const int kMaxSignificantDecimalDigits = 780; + + static Vector TrimLeadingZeros(Vector buffer) + { + for (int i = 0; i < buffer.length(); i++) + { + if (buffer[i] != '0') + { + return buffer.SubVector(i, buffer.length()); + } + } + return new Vector(buffer.bytes, buffer.start, 0); + } + + static Vector TrimTrailingZeros(Vector buffer) + { + for (int i = buffer.length() - 1; i >= 0; --i) + { + if (buffer[i] != '0') + { + return buffer.SubVector(0, i + 1); + } + } + return new Vector(buffer.bytes, buffer.start, 0); + } + + + static void CutToMaxSignificantDigits(Vector buffer, + int exponent, + byte[] significant_buffer, + out int significant_exponent) + { + for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) + { + significant_buffer[i] = buffer[i]; + } + // The input buffer has been trimmed. Therefore the last digit must be + // different from '0'. + // ASSERT(buffer[buffer.length() - 1] != '0'); + // Set the last digit to be non-zero. This is sufficient to guarantee + // correct rounding. + significant_buffer[kMaxSignificantDecimalDigits - 1] = (byte)'1'; + significant_exponent = exponent + (buffer.length() - kMaxSignificantDecimalDigits); + } + + // Trims the buffer and cuts it to at most kMaxSignificantDecimalDigits. + // If possible the input-buffer is reused, but if the buffer needs to be + // modified (due to cutting), then the input needs to be copied into the + // buffer_copy_space. + static void TrimAndCut(Vector buffer, int exponent, + byte[] buffer_copy_space, int space_size, + out Vector trimmed, out int updated_exponent) + { + Vector left_trimmed = TrimLeadingZeros(buffer); + Vector right_trimmed = TrimTrailingZeros(left_trimmed); + exponent += left_trimmed.length() - right_trimmed.length(); + if (right_trimmed.length() > kMaxSignificantDecimalDigits) + { + // (void)space_size; // Mark variable as used. + CutToMaxSignificantDigits(right_trimmed, exponent, + buffer_copy_space, out updated_exponent); + trimmed = new Vector(buffer_copy_space, 0, kMaxSignificantDecimalDigits); + } + else + { + trimmed = right_trimmed; + updated_exponent = exponent; + } + } + + + // Reads digits from the buffer and converts them to a uint64. + // Reads in as many digits as fit into a uint64. + // When the string starts with "1844674407370955161" no further digit is read. + // Since 2^64 = 18446744073709551616 it would still be possible read another + // digit if it was less or equal than 6, but this would complicate the code. + static uint64_t ReadUint64(Vector buffer, + out int number_of_read_digits) + { + uint64_t result = 0; + int i = 0; + while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) + { + int digit = buffer[i++] - '0'; + result = 10 * result + (ulong)digit; + } + number_of_read_digits = i; + return result; + } + + // Reads a DiyFp from the buffer. + // The returned DiyFp is not necessarily normalized. + // If remaining_decimals is zero then the returned DiyFp is accurate. + // Otherwise it has been rounded and has error of at most 1/2 ulp. + static void ReadDiyFp(Vector buffer, + out DiyFp result, + out int remaining_decimals) + { + int read_digits; + uint64_t significand = ReadUint64(buffer, out read_digits); + if (buffer.length() == read_digits) + { + result = new DiyFp(significand, 0); + remaining_decimals = 0; + } + else + { + // Round the significand. + if (buffer[read_digits] >= '5') + { + significand++; + } + // Compute the binary exponent. + int exponent = 0; + result = new DiyFp(significand, exponent); + remaining_decimals = buffer.length() - read_digits; + } + } + + + static bool DoubleStrtod(Vector trimmed, + int exponent, + out double result) + { + if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) + { + int read_digits; + // The trimmed input fits into a double. + // If the 10^exponent (resp. 10^-exponent) fits into a double too then we + // can compute the result-double simply by multiplying (resp. dividing) the + // two numbers. + // This is possible because IEEE guarantees that floating-point operations + // return the best possible approximation. + if (exponent < 0 && -exponent < kExactPowersOfTenSize) + { + // 10^-exponent fits into a double. + result = unchecked((double)(ReadUint64(trimmed, out read_digits))); + result /= exact_powers_of_ten[-exponent]; + return true; + } + if (0 <= exponent && exponent < kExactPowersOfTenSize) + { + // 10^exponent fits into a double. + result = unchecked((double)(ReadUint64(trimmed, out read_digits))); + result *= exact_powers_of_ten[exponent]; + return true; + } + int remaining_digits = + kMaxExactDoubleIntegerDecimalDigits - trimmed.length(); + if ((0 <= exponent) && + (exponent - remaining_digits < kExactPowersOfTenSize)) + { + // The trimmed string was short and we can multiply it with + // 10^remaining_digits. As a result the remaining exponent now fits + // into a double too. + result = unchecked((double)(ReadUint64(trimmed, out read_digits))); + result *= exact_powers_of_ten[remaining_digits]; + result *= exact_powers_of_ten[exponent - remaining_digits]; + return true; + } + } + result = 0; + return false; + } + + + // Returns 10^exponent as an exact DiyFp. + // The given exponent must be in the range [1; kDecimalExponentDistance[. + static DiyFp AdjustmentPowerOfTen(int exponent) + { + // Simply hardcode the remaining powers for the given decimal exponent + // distance. + switch (exponent) + { + case 1: return new DiyFp(0xa000000000000000, -60); + case 2: return new DiyFp(0xc800000000000000, -57); + case 3: return new DiyFp(0xfa00000000000000, -54); + case 4: return new DiyFp(0x9c40000000000000, -50); + case 5: return new DiyFp(0xc350000000000000, -47); + case 6: return new DiyFp(0xf424000000000000, -44); + case 7: return new DiyFp(0x9896800000000000, -40); + default: + throw new Exception("unreached code."); + } + } + + // If the function returns true then the result is the correct double. + // Otherwise it is either the correct double or the double that is just below + // the correct double. + static bool DiyFpStrtod(Vector buffer, + int exponent, + out double result) + { + DiyFp input; + int remaining_decimals; + ReadDiyFp(buffer, out input, out remaining_decimals); + // Since we may have dropped some digits the input is not accurate. + // If remaining_decimals is different than 0 than the error is at most + // .5 ulp (unit in the last place). + // We don't want to deal with fractions and therefore keep a common + // denominator. + const int kDenominatorLog = 3; + const int kDenominator = 1 << kDenominatorLog; + // Move the remaining decimals into the exponent. + exponent += remaining_decimals; + uint64_t error = (ulong)(remaining_decimals == 0 ? 0 : kDenominator / 2); + + int old_e = input.e; + input.Normalize(); + error <<= old_e - input.e; + + if (exponent < PowersOfTenCache.kMinDecimalExponent) + { + result = 0.0; + return true; + } + DiyFp cached_power; + int cached_decimal_exponent; + PowersOfTenCache.GetCachedPowerForDecimalExponent(exponent, + out cached_power, + out cached_decimal_exponent); + + if (cached_decimal_exponent != exponent) + { + int adjustment_exponent = exponent - cached_decimal_exponent; + DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent); + input.Multiply(ref adjustment_power); + if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) + { + // The product of input with the adjustment power fits into a 64 bit + // integer. + } + else + { + // The adjustment power is exact. There is hence only an error of 0.5. + error += kDenominator / 2; + } + } + + input.Multiply(ref cached_power); + // The error introduced by a multiplication of a*b equals + // error_a + error_b + error_a*error_b/2^64 + 0.5 + // Substituting a with 'input' and b with 'cached_power' we have + // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp), + // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64 + int error_b = kDenominator / 2; + int error_ab = (error == 0 ? 0 : 1); // We round up to 1. + int fixed_error = kDenominator / 2; + error += (ulong)(error_b + error_ab + fixed_error); + + old_e = input.e; + input.Normalize(); + error <<= old_e - input.e; + + // See if the double's significand changes if we add/subtract the error. + int order_of_magnitude = DiyFp.kSignificandSize + input.e; + int effective_significand_size = Double.SignificandSizeForOrderOfMagnitude(order_of_magnitude); + int precision_digits_count = DiyFp.kSignificandSize - effective_significand_size; + if (precision_digits_count + kDenominatorLog >= DiyFp.kSignificandSize) + { + // This can only happen for very small denormals. In this case the + // half-way multiplied by the denominator exceeds the range of an uint64. + // Simply shift everything to the right. + int shift_amount = (precision_digits_count + kDenominatorLog) - + DiyFp.kSignificandSize + 1; + input.f = (input.f >> shift_amount); + input.e = (input.e + shift_amount); + // We add 1 for the lost precision of error, and kDenominator for + // the lost precision of input.f(). + error = (error >> shift_amount) + 1 + kDenominator; + precision_digits_count -= shift_amount; + } + // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too. + uint64_t one64 = 1; + uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1; + uint64_t precision_bits = input.f & precision_bits_mask; + uint64_t half_way = one64 << (precision_digits_count - 1); + precision_bits *= kDenominator; + half_way *= kDenominator; + DiyFp rounded_input = new DiyFp(input.f >> precision_digits_count, input.e + precision_digits_count); + if (precision_bits >= half_way + error) + { + rounded_input.f = (rounded_input.f + 1); + } + // If the last_bits are too close to the half-way case than we are too + // inaccurate and round down. In this case we return false so that we can + // fall back to a more precise algorithm. + + result = new Double(rounded_input).value(); + if (half_way - error < precision_bits && precision_bits < half_way + error) + { + // Too imprecise. The caller will have to fall back to a slower version. + // However the returned number is guaranteed to be either the correct + // double, or the next-lower double. + return false; + } + else + { + return true; + } + } + + // Returns true if the guess is the correct double. + // Returns false, when guess is either correct or the next-lower double. + static bool ComputeGuess(Vector trimmed, int exponent, + out double guess) + { + if (trimmed.length() == 0) + { + guess = 0.0; + return true; + } + if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) + { + guess = Double.Infinity(); + return true; + } + if (exponent + trimmed.length() <= kMinDecimalPower) + { + guess = 0.0; + return true; + } + + if (DoubleStrtod(trimmed, exponent, out guess) || + DiyFpStrtod(trimmed, exponent, out guess)) + { + return true; + } + if (guess == Double.Infinity()) + { + return true; + } + return false; + } + + public static double? Strtod(Vector buffer, int exponent) + { + byte[] copy_buffer = GetCopyBuffer(); + Vector trimmed; + int updated_exponent; + TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, + out trimmed, out updated_exponent); + exponent = updated_exponent; + + double guess; + var is_correct = ComputeGuess(trimmed, exponent, out guess); + if (is_correct) return guess; + return null; + } + + public static float? Strtof(Vector buffer, int exponent) + { + byte[] copy_buffer = GetCopyBuffer(); + Vector trimmed; + int updated_exponent; + TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, + out trimmed, out updated_exponent); + exponent = updated_exponent; + + double double_guess; + var is_correct = ComputeGuess(trimmed, exponent, out double_guess); + + float float_guess = (float)(double_guess); + if (float_guess == double_guess) + { + // This shortcut triggers for integer values. + return float_guess; + } + + // We must catch double-rounding. Say the double has been rounded up, and is + // now a boundary of a float, and rounds up again. This is why we have to + // look at previous too. + // Example (in decimal numbers): + // input: 12349 + // high-precision (4 digits): 1235 + // low-precision (3 digits): + // when read from input: 123 + // when rounded from high precision: 124. + // To do this we simply look at the neigbors of the correct result and see + // if they would round to the same float. If the guess is not correct we have + // to look at four values (since two different doubles could be the correct + // double). + + double double_next = new Double(double_guess).NextDouble(); + double double_previous = new Double(double_guess).PreviousDouble(); + + float f1 = (float)(double_previous); + // float f2 = float_guess; + float f3 = (float)(double_next); + float f4; + if (is_correct) + { + f4 = f3; + } + else + { + double double_next2 = new Double(double_next).NextDouble(); + f4 = (float)(double_next2); + } + // (void)f2; // Mark variable as used. + + // If the guess doesn't lie near a single-precision boundary we can simply + // return its float-value. + if (f1 == f4) + { + return float_guess; + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs b/src/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs new file mode 100644 index 00000000..67cbe2a1 --- /dev/null +++ b/src/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs @@ -0,0 +1,625 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text.Internal +{ +#pragma warning disable 660 +#pragma warning disable 661 + + internal struct Iterator + { + byte[] buffer; + int offset; + + public Iterator(byte[] buffer, int offset) + { + this.buffer = buffer; + this.offset = offset; + } + + public byte Value + { + get + { + return buffer[offset]; + } + } + + public static Iterator operator ++(Iterator self) + { + self.offset++; + return self; + } + + public static Iterator operator +(Iterator self, int length) + { + return new Iterator { buffer = self.buffer, offset = self.offset + length }; + } + + public static int operator -(Iterator lhs, Iterator rhs) + { + return lhs.offset - rhs.offset; + } + + public static bool operator ==(Iterator lhs, Iterator rhs) + { + return lhs.offset == rhs.offset; + } + + public static bool operator !=(Iterator lhs, Iterator rhs) + { + return lhs.offset != rhs.offset; + } + + public static bool operator ==(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] == (byte)rhs; + } + + public static bool operator !=(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] != (byte)rhs; + } + + public static bool operator ==(Iterator lhs, byte rhs) + { + return lhs.buffer[lhs.offset] == (byte)rhs; + } + + public static bool operator !=(Iterator lhs, byte rhs) + { + return lhs.buffer[lhs.offset] != (byte)rhs; + } + + public static bool operator >=(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] >= (byte)rhs; + } + + public static bool operator <=(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] <= (byte)rhs; + } + + public static bool operator >(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] > (byte)rhs; + } + + public static bool operator <(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] < (byte)rhs; + } + } + +#pragma warning restore 661 +#pragma warning restore 660 + + // C# API + internal static partial class StringToDoubleConverter + { + [ThreadStatic] + static byte[] kBuffer; + + static byte[] GetBuffer() + { + if (kBuffer == null) + { + kBuffer = new byte[kBufferSize]; + } + return kBuffer; + } + + [ThreadStatic] + static byte[] fallbackBuffer; + + static byte[] GetFallbackBuffer() + { + if (fallbackBuffer == null) + { + fallbackBuffer = new byte[99]; + } + return fallbackBuffer; + } + + public static double ToDouble(byte[] buffer, int offset, out int readCount) + { + return StringToIeee(new Iterator(buffer, offset), buffer.Length - offset, true, out readCount); + } + + public static float ToSingle(byte[] buffer, int offset, out int readCount) + { + return unchecked((float)StringToIeee(new Iterator(buffer, offset), buffer.Length - offset, false, out readCount)); + } + } + + // port + internal static partial class StringToDoubleConverter + { + enum Flags + { + NO_FLAGS = 0, + ALLOW_HEX = 1, // defined but always disallow + ALLOW_OCTALS = 2, + ALLOW_TRAILING_JUNK = 4, + ALLOW_LEADING_SPACES = 8, + ALLOW_TRAILING_SPACES = 16, + ALLOW_SPACES_AFTER_SIGN = 32, + ALLOW_CASE_INSENSIBILITY = 64, // not supported + }; + + const Flags flags_ = Flags.ALLOW_TRAILING_JUNK | Flags.ALLOW_TRAILING_SPACES | Flags.ALLOW_SPACES_AFTER_SIGN; + const double empty_string_value_ = 0.0; + const double junk_string_value_ = double.NaN; + const int kMaxSignificantDigits = 772; + const int kBufferSize = kMaxSignificantDigits + 10; + static readonly byte[] infinity_symbol_ = Encoding.UTF8.GetBytes(double.PositiveInfinity.ToString()); + static readonly byte[] nan_symbol_ = Encoding.UTF8.GetBytes(double.NaN.ToString()); + + static readonly byte[] kWhitespaceTable7 = new byte[] { 32, 13, 10, 9, 11, 12 }; + static readonly int kWhitespaceTable7Length = kWhitespaceTable7.Length; + + static readonly UInt16[] kWhitespaceTable16 = new UInt16[]{ + 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195, + 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279 + }; + static readonly int kWhitespaceTable16Length = kWhitespaceTable16.Length; + + static bool isWhitespace(int x) + { + if (x < 128) + { + for (int i = 0; i < kWhitespaceTable7Length; i++) + { + if (kWhitespaceTable7[i] == x) return true; + } + } + else + { + for (int i = 0; i < kWhitespaceTable16Length; i++) + { + if (kWhitespaceTable16[i] == x) return true; + } + } + return false; + } + + static bool AdvanceToNonspace(ref Iterator current, Iterator end) + { + while (current != end) + { + if (!isWhitespace(current.Value)) return true; + current++; + } + return false; + } + + static bool ConsumeSubString(ref Iterator current, + Iterator end, + byte[] substring) + { + for (int i = 1; i < substring.Length; i++) + { + ++current; + if (current == end || current != substring[i]) + { + return false; + } + } + ++current; + return true; + } + + + // Consumes first character of the str is equal to ch + static bool ConsumeFirstCharacter(ref Iterator iter, + byte[] str, + int offset) + { + return iter.Value == str[offset]; + } + + static double SignedZero(bool sign) + { + return sign ? -0.0 : 0.0; + } + + static double StringToIeee( + Iterator input, + int length, + bool read_as_double, + out int processed_characters_count) + { + Iterator current = input; + Iterator end = input + length; + + processed_characters_count = 0; + + bool allow_trailing_junk = (flags_ & Flags.ALLOW_TRAILING_JUNK) != 0; + bool allow_leading_spaces = (flags_ & Flags.ALLOW_LEADING_SPACES) != 0; + bool allow_trailing_spaces = (flags_ & Flags.ALLOW_TRAILING_SPACES) != 0; + bool allow_spaces_after_sign = (flags_ & Flags.ALLOW_SPACES_AFTER_SIGN) != 0; + // bool allow_case_insensibility = (flags_ & Flags.ALLOW_CASE_INSENSIBILITY) != 0; + + // To make sure that iterator dereferencing is valid the following + // convention is used: + // 1. Each '++current' statement is followed by check for equality to 'end'. + // 2. If AdvanceToNonspace returned false then current == end. + // 3. If 'current' becomes equal to 'end' the function returns or goes to + // 'parsing_done'. + // 4. 'current' is not dereferenced after the 'parsing_done' label. + // 5. Code before 'parsing_done' may rely on 'current != end'. + if (length == 0) return empty_string_value_; + + if (allow_leading_spaces || allow_trailing_spaces) + { + if (!AdvanceToNonspace(ref current, end)) + { + processed_characters_count = (int)(current - input); + return empty_string_value_; + } + if (!allow_leading_spaces && (input != current)) + { + // No leading spaces allowed, but AdvanceToNonspace moved forward. + return junk_string_value_; + } + } + + // The longest form of simplified number is: "-.1eXXX\0". + byte[] buffer = GetBuffer(); // NOLINT: size is known at compile time. + int buffer_pos = 0; + + // Exponent will be adjusted if insignificant digits of the integer part + // or insignificant leading zeros of the fractional part are dropped. + int exponent = 0; + int significant_digits = 0; + int insignificant_digits = 0; + bool nonzero_digit_dropped = false; + + bool sign = false; + + if (current == '+' || current == '-') + { + sign = (current == '-'); + current++; + Iterator next_non_space = current; + // Skip following spaces (if allowed). + if (!AdvanceToNonspace(ref next_non_space, end)) return junk_string_value_; + if (!allow_spaces_after_sign && (current != next_non_space)) + { + return junk_string_value_; + } + current = next_non_space; + } + + if (infinity_symbol_ != null) + { + if (ConsumeFirstCharacter(ref current, infinity_symbol_, 0)) + { + if (!ConsumeSubString(ref current, end, infinity_symbol_)) + { + return junk_string_value_; + } + + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) + { + return junk_string_value_; + } + if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) + { + return junk_string_value_; + } + + processed_characters_count = (current - input); + return sign ? double.NegativeInfinity : double.PositiveInfinity; + } + } + + if (nan_symbol_ != null) + { + if (ConsumeFirstCharacter(ref current, nan_symbol_, 0)) + { + if (!ConsumeSubString(ref current, end, nan_symbol_)) + { + return junk_string_value_; + } + + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) + { + return junk_string_value_; + } + if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) + { + return junk_string_value_; + } + + processed_characters_count = (current - input); + return sign ? -double.NaN : double.NaN; + } + } + + bool leading_zero = false; + if (current == '0') + { + current++; + if (current == end) + { + processed_characters_count = (current - input); + return SignedZero(sign); + } + + leading_zero = true; + + // It could be hexadecimal value. + //if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) + //{ + // ++current; + // if (current == end || !isDigit(*current, 16)) + // { + // return junk_string_value_; // "0x". + // } + + // bool result_is_junk; + // double result = RadixStringToIeee < 4 > (¤t, + // end, + // sign, + // allow_trailing_junk, + // junk_string_value_, + // read_as_double, + // &result_is_junk); + // if (!result_is_junk) + // { + // if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); + // *processed_characters_count = static_cast(current - input); + // } + // return result; + //} + + // Ignore leading zeros in the integer part. + while (current == '0') + { + current++; + if (current == end) + { + processed_characters_count = (current - input); + return SignedZero(sign); + } + } + } + + bool octal = leading_zero && (flags_ & Flags.ALLOW_OCTALS) != 0; + + // Copy significant digits of the integer part (if any) to the buffer. + while (current >= '0' && current <= '9') + { + if (significant_digits < kMaxSignificantDigits) + { + buffer[buffer_pos++] = (current.Value); + significant_digits++; + // Will later check if it's an octal in the buffer. + } + else + { + insignificant_digits++; // Move the digit into the exponential part. + nonzero_digit_dropped = nonzero_digit_dropped || current != '0'; + } + // octal = octal && *current < '8'; + current++; + if (current == end) goto parsing_done; + } + + if (significant_digits == 0) + { + octal = false; + } + + if (current == '.') + { + if (octal && !allow_trailing_junk) return junk_string_value_; + if (octal) goto parsing_done; + + current++; + if (current == end) + { + if (significant_digits == 0 && !leading_zero) + { + return junk_string_value_; + } + else + { + goto parsing_done; + } + } + + if (significant_digits == 0) + { + // octal = false; + // Integer part consists of 0 or is absent. Significant digits start after + // leading zeros (if any). + while (current == '0') + { + ++current; + if (current == end) + { + processed_characters_count = (current - input); + return SignedZero(sign); + } + exponent--; // Move this 0 into the exponent. + } + } + + // There is a fractional part. + // We don't emit a '.', but adjust the exponent instead. + while (current >= '0' && current <= '9') + { + if (significant_digits < kMaxSignificantDigits) + { + buffer[buffer_pos++] = current.Value; + significant_digits++; + exponent--; + } + else + { + // Ignore insignificant digits in the fractional part. + nonzero_digit_dropped = nonzero_digit_dropped || current != '0'; + } + ++current; + if (current == end) goto parsing_done; + } + } + + if (!leading_zero && exponent == 0 && significant_digits == 0) + { + // If leading_zeros is true then the string contains zeros. + // If exponent < 0 then string was [+-]\.0*... + // If significant_digits != 0 the string is not equal to 0. + // Otherwise there are no digits in the string. + return junk_string_value_; + } + + // Parse exponential part. + if (current == 'e' || current == 'E') + { + if (octal && !allow_trailing_junk) return junk_string_value_; + if (octal) goto parsing_done; + ++current; + if (current == end) + { + if (allow_trailing_junk) + { + goto parsing_done; + } + else + { + return junk_string_value_; + } + } + byte exponen_sign = (byte)'+'; + if (current == '+' || current == '-') + { + exponen_sign = current.Value; + ++current; + if (current == end) + { + if (allow_trailing_junk) + { + goto parsing_done; + } + else + { + return junk_string_value_; + } + } + } + + if (current == end || current < '0' || current > '9') + { + if (allow_trailing_junk) + { + goto parsing_done; + } + else + { + return junk_string_value_; + } + } + + const int max_exponent = int.MaxValue / 2; + + int num = 0; + do + { + // Check overflow. + int digit = current.Value - (byte)'0'; + if (num >= max_exponent / 10 + && !(num == max_exponent / 10 && digit <= max_exponent % 10)) + { + num = max_exponent; + } + else + { + num = num * 10 + digit; + } + ++current; + } while (current != end && current >= '0' && current <= '9'); + + exponent += (exponen_sign == '-' ? -num : num); + } + + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) + { + return junk_string_value_; + } + if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) + { + return junk_string_value_; + } + if (allow_trailing_spaces) + { + AdvanceToNonspace(ref current, end); + } + + parsing_done: + exponent += insignificant_digits; + + //if (octal) + //{ + // double result; + // bool result_is_junk; + // char* start = buffer; + // result = RadixStringToIeee < 3 > (&start, + // buffer + buffer_pos, + // sign, + // allow_trailing_junk, + // junk_string_value_, + // read_as_double, + // &result_is_junk); + // ASSERT(!result_is_junk); + // *processed_characters_count = static_cast(current - input); + // return result; + //} + + if (nonzero_digit_dropped) + { + buffer[buffer_pos++] = (byte)'1'; + exponent--; + } + + buffer[buffer_pos] = (byte)'\0'; + + double? converted; + if (read_as_double) + { + converted = StringToDouble.Strtod(new Vector(buffer, 0, buffer_pos), exponent); + } + else + { + converted = StringToDouble.Strtof(new Vector(buffer, 0, buffer_pos), exponent); + } + + if (converted == null) + { + // read-again + processed_characters_count = (current - input); + + var fallbackbuffer = GetFallbackBuffer(); + if (fallbackBuffer.Length < processed_characters_count) + { + Array.Resize(ref fallbackBuffer, processed_characters_count); + } + var fallbackI = 0; + while (input != current) + { + fallbackbuffer[fallbackI++] = input.Value; + input++; + } + var laststr = Encoding.UTF8.GetString(fallbackbuffer, 0, fallbackI); + return double.Parse(laststr); + } + + processed_characters_count = (current - input); + return sign ? -converted.Value : converted.Value; + } + } +} diff --git a/src/ZString/Shims/Shims.cs b/src/ZString/Shims/Shims.cs new file mode 100644 index 00000000..d1a5764f --- /dev/null +++ b/src/ZString/Shims/Shims.cs @@ -0,0 +1,482 @@ +using Cysharp.Text.Internal; +using System; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Cysharp.Text +{ + internal static class Int32 + { + /// 0 ~ 9 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNumber(char c) + { + return '0' <= c && c <= '9'; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Parse(ReadOnlySpan s) + { + var value = 0L; + var sign = 1; + + if (s[0] == '-') + { + sign = -1; + } + + for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) + { + if (!IsNumber(s[i])) + { + goto END; + } + + // long.MinValue causes overflow so use unchecked. + value = unchecked(value * 10 + ((byte)s[i] - '0')); + } + + END: + return checked((int)(unchecked(value * sign))); + } + } + + public static class ShimsExtensions + { + public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) + { + fixed (char* src = span) + fixed (byte* dest = bytes) + { + return encoding.GetBytes(src, span.Length, dest, bytes.Length); + } + } + + public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return DoubleToStringConverter.TryFormat(destination, value, out charsWritten); + } + + public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return DoubleToStringConverter.TryFormat(destination, value, out charsWritten); + } + + public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + static string GetFormat(ReadOnlySpan format) + { + if (format.Length == 0) + { + return null; + } + return format.ToString(); + } + + static bool TryWriteInt64(Span buffer, out int charsWritten, long value) + { + var offset = 0; + charsWritten = 0; + long num1 = value, num2, num3, num4, num5, div; + + if (value < 0) + { + if (value == long.MinValue) // -9223372036854775808 + { + if (buffer.Length < 20) { return false; } + buffer[offset++] = (char)'-'; + buffer[offset++] = (char)'9'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'0'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'6'; + buffer[offset++] = (char)'8'; + buffer[offset++] = (char)'5'; + buffer[offset++] = (char)'4'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'5'; + buffer[offset++] = (char)'8'; + buffer[offset++] = (char)'0'; + buffer[offset++] = (char)'8'; + charsWritten = offset; + return true; + } + + if (buffer.Length < 1) { return false; } + buffer[offset++] = (char)'-'; + num1 = unchecked(-value); + } + + // WriteUInt64(inlined) + + if (num1 < 10000) + { + if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } + if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } + if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } + if (buffer.Length < 4) { return false; } + goto L4; + } + else + { + num2 = num1 / 10000; + num1 -= num2 * 10000; + if (num2 < 10000) + { + if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } + if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } + if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } + if (buffer.Length < 8) { return false; } + goto L8; + } + else + { + num3 = num2 / 10000; + num2 -= num3 * 10000; + if (num3 < 10000) + { + if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } + if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } + if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } + if (buffer.Length < 12) { return false; } + goto L12; + } + else + { + num4 = num3 / 10000; + num3 -= num4 * 10000; + if (num4 < 10000) + { + if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } + if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } + if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } + if (buffer.Length < 16) { return false; } + goto L16; + } + else + { + num5 = num4 / 10000; + num4 -= num5 * 10000; + if (num5 < 10000) + { + if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } + if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } + if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } + if (buffer.Length < 20) { return false; } + goto L20; + } + L20: + buffer[offset++] = (char)('0' + (div = (num5 * 8389L) >> 23)); + num5 -= div * 1000; + L19: + buffer[offset++] = (char)('0' + (div = (num5 * 5243L) >> 19)); + num5 -= div * 100; + L18: + buffer[offset++] = (char)('0' + (div = (num5 * 6554L) >> 16)); + num5 -= div * 10; + L17: + buffer[offset++] = (char)('0' + (num5)); + } + L16: + buffer[offset++] = (char)('0' + (div = (num4 * 8389L) >> 23)); + num4 -= div * 1000; + L15: + buffer[offset++] = (char)('0' + (div = (num4 * 5243L) >> 19)); + num4 -= div * 100; + L14: + buffer[offset++] = (char)('0' + (div = (num4 * 6554L) >> 16)); + num4 -= div * 10; + L13: + buffer[offset++] = (char)('0' + (num4)); + } + L12: + buffer[offset++] = (char)('0' + (div = (num3 * 8389L) >> 23)); + num3 -= div * 1000; + L11: + buffer[offset++] = (char)('0' + (div = (num3 * 5243L) >> 19)); + num3 -= div * 100; + L10: + buffer[offset++] = (char)('0' + (div = (num3 * 6554L) >> 16)); + num3 -= div * 10; + L9: + buffer[offset++] = (char)('0' + (num3)); + } + L8: + buffer[offset++] = (char)('0' + (div = (num2 * 8389L) >> 23)); + num2 -= div * 1000; + L7: + buffer[offset++] = (char)('0' + (div = (num2 * 5243L) >> 19)); + num2 -= div * 100; + L6: + buffer[offset++] = (char)('0' + (div = (num2 * 6554L) >> 16)); + num2 -= div * 10; + L5: + buffer[offset++] = (char)('0' + (num2)); + } + L4: + buffer[offset++] = (char)('0' + (div = (num1 * 8389L) >> 23)); + num1 -= div * 1000; + L3: + buffer[offset++] = (char)('0' + (div = (num1 * 5243L) >> 19)); + num1 -= div * 100; + L2: + buffer[offset++] = (char)('0' + (div = (num1 * 6554L) >> 16)); + num1 -= div * 10; + L1: + buffer[offset++] = (char)('0' + (num1)); + + charsWritten = offset; + return true; + } + + static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) + { + ulong num1 = value, num2, num3, num4, num5, div; + charsWritten = 0; + var offset = 0; + + if (num1 < 10000) + { + if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } + if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } + if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } + if (buffer.Length < 4) { return false; } + goto L4; + } + else + { + num2 = num1 / 10000; + num1 -= num2 * 10000; + if (num2 < 10000) + { + if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } + if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } + if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } + if (buffer.Length < 8) { return false; } + goto L8; + } + else + { + num3 = num2 / 10000; + num2 -= num3 * 10000; + if (num3 < 10000) + { + if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } + if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } + if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } + if (buffer.Length < 12) { return false; } + goto L12; + } + else + { + num4 = num3 / 10000; + num3 -= num4 * 10000; + if (num4 < 10000) + { + if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } + if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } + if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } + if (buffer.Length < 16) { return false; } + goto L16; + } + else + { + num5 = num4 / 10000; + num4 -= num5 * 10000; + if (num5 < 10000) + { + if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } + if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } + if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } + if (buffer.Length < 20) { return false; } + goto L20; + } + L20: + buffer[offset++] = (char)('0' + (div = (num5 * 8389UL) >> 23)); + num5 -= div * 1000; + L19: + buffer[offset++] = (char)('0' + (div = (num5 * 5243UL) >> 19)); + num5 -= div * 100; + L18: + buffer[offset++] = (char)('0' + (div = (num5 * 6554UL) >> 16)); + num5 -= div * 10; + L17: + buffer[offset++] = (char)('0' + (num5)); + } + L16: + buffer[offset++] = (char)('0' + (div = (num4 * 8389UL) >> 23)); + num4 -= div * 1000; + L15: + buffer[offset++] = (char)('0' + (div = (num4 * 5243UL) >> 19)); + num4 -= div * 100; + L14: + buffer[offset++] = (char)('0' + (div = (num4 * 6554UL) >> 16)); + num4 -= div * 10; + L13: + buffer[offset++] = (char)('0' + (num4)); + } + L12: + buffer[offset++] = (char)('0' + (div = (num3 * 8389UL) >> 23)); + num3 -= div * 1000; + L11: + buffer[offset++] = (char)('0' + (div = (num3 * 5243UL) >> 19)); + num3 -= div * 100; + L10: + buffer[offset++] = (char)('0' + (div = (num3 * 6554UL) >> 16)); + num3 -= div * 10; + L9: + buffer[offset++] = (char)('0' + (num3)); + } + L8: + buffer[offset++] = (char)('0' + (div = (num2 * 8389UL) >> 23)); + num2 -= div * 1000; + L7: + buffer[offset++] = (char)('0' + (div = (num2 * 5243UL) >> 19)); + num2 -= div * 100; + L6: + buffer[offset++] = (char)('0' + (div = (num2 * 6554UL) >> 16)); + num2 -= div * 10; + L5: + buffer[offset++] = (char)('0' + (num2)); + } + L4: + buffer[offset++] = (char)('0' + (div = (num1 * 8389UL) >> 23)); + num1 -= div * 1000; + L3: + buffer[offset++] = (char)('0' + (div = (num1 * 5243UL) >> 19)); + num1 -= div * 100; + L2: + buffer[offset++] = (char)('0' + (div = (num1 * 6554UL) >> 16)); + num1 -= div * 10; + L1: + buffer[offset++] = (char)('0' + (num1)); + + charsWritten = offset; + return true; + } + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 2cca20e5..76f1cc3a 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -4,7 +4,7 @@ namespace Cysharp.Text { public ref partial struct Utf16ValueStringBuilder { - public void AppendFormat(ReadOnlySpan format, T0 arg0) + public void AppendFormat(string format, T0 arg0) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -21,7 +21,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0) { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -31,12 +31,12 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0) { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -72,19 +72,19 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0) if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0) + public void AppendFormatLine(string format, T0 arg0) { AppendFormat(format, arg0); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) + public void AppendFormat(string format, T0 arg0, T1 arg1) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -101,7 +101,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -111,12 +111,12 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -165,19 +165,19 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1) + public void AppendFormatLine(string format, T0 arg0, T1 arg1) { AppendFormat(format, arg0, arg1); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -194,7 +194,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1 { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -204,12 +204,12 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1 { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -271,19 +271,19 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1 if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2) { AppendFormat(format, arg0, arg1, arg2); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -300,7 +300,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -310,12 +310,12 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -390,19 +390,19 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { AppendFormat(format, arg0, arg1, arg2, arg3); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -419,7 +419,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -429,12 +429,12 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -522,19 +522,19 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -551,7 +551,7 @@ public void AppendFormat(ReadOnlySpan format, T0 a { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -561,12 +561,12 @@ public void AppendFormat(ReadOnlySpan format, T0 a { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -667,19 +667,19 @@ public void AppendFormat(ReadOnlySpan format, T0 a if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -696,7 +696,7 @@ public void AppendFormat(ReadOnlySpan format, { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -706,12 +706,12 @@ public void AppendFormat(ReadOnlySpan format, { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -825,19 +825,19 @@ public void AppendFormat(ReadOnlySpan format, if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -854,7 +854,7 @@ public void AppendFormat(ReadOnlySpan form { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -864,12 +864,12 @@ public void AppendFormat(ReadOnlySpan form { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -996,19 +996,19 @@ public void AppendFormat(ReadOnlySpan form if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1025,7 +1025,7 @@ public void AppendFormat(ReadOnlySpan { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -1035,12 +1035,12 @@ public void AppendFormat(ReadOnlySpan { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -1180,19 +1180,19 @@ public void AppendFormat(ReadOnlySpan if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1209,7 +1209,7 @@ public void AppendFormat(ReadOnlySpan(ReadOnlySpan(ReadOnlySpan 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1406,7 +1406,7 @@ public void AppendFormat(ReadOnlySp { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -1416,12 +1416,12 @@ public void AppendFormat(ReadOnlySp { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -1587,19 +1587,19 @@ public void AppendFormat(ReadOnlySp if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1616,7 +1616,7 @@ public void AppendFormat(ReadO { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -1626,12 +1626,12 @@ public void AppendFormat(ReadO { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -1810,19 +1810,19 @@ public void AppendFormat(ReadO if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1839,7 +1839,7 @@ public void AppendFormat( { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -1849,12 +1849,12 @@ public void AppendFormat( { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -2046,19 +2046,19 @@ public void AppendFormat( if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2075,7 +2075,7 @@ public void AppendFormat 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2324,7 +2324,7 @@ public void AppendFormat 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2586,7 +2586,7 @@ public void AppendFormat 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); AppendNewLine(); diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt index f40f341e..662c7980 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt @@ -28,7 +28,7 @@ namespace Cysharp.Text public ref partial struct Utf16ValueStringBuilder { <# for(var i = 1; i <= 16; i++) { #> - public void AppendFormat<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -45,7 +45,7 @@ namespace Cysharp.Text { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; i = i + 1; // skip escaped '{' copyFrom = i; @@ -55,12 +55,12 @@ namespace Cysharp.Text { var size = i - copyFrom; TryGrow(size); - format.Slice(copyFrom, size).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); index += size; } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -98,13 +98,13 @@ namespace Cysharp.Text if (copyLength > 0) { TryGrow(copyLength); - format.Slice(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); index += copyLength; } } } - public void AppendFormatLine<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + public void AppendFormatLine<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { AppendFormat(format, <#= CreateParameterNames(i) #>); AppendNewLine(); diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index 20fb6fff..9e928305 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -4,7 +4,7 @@ namespace Cysharp.Text { public ref partial struct Utf8ValueStringBuilder { - public void AppendFormat(ReadOnlySpan format, T0 arg0) + public void AppendFormat(string format, T0 arg0) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -21,7 +21,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0) { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -30,11 +30,11 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0) { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -70,18 +70,18 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0) if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0) + public void AppendFormatLine(string format, T0 arg0) { AppendFormat(format, arg0); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) + public void AppendFormat(string format, T0 arg0, T1 arg1) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -98,7 +98,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -107,11 +107,11 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -160,18 +160,18 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1) if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1) + public void AppendFormatLine(string format, T0 arg0, T1 arg1) { AppendFormat(format, arg0, arg1); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -188,7 +188,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1 { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -197,11 +197,11 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1 { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -263,18 +263,18 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1 if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2) { AppendFormat(format, arg0, arg1, arg2); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -291,7 +291,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -300,11 +300,11 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -379,18 +379,18 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { AppendFormat(format, arg0, arg1, arg2, arg3); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -407,7 +407,7 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -416,11 +416,11 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -508,18 +508,18 @@ public void AppendFormat(ReadOnlySpan format, T0 arg0, if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -536,7 +536,7 @@ public void AppendFormat(ReadOnlySpan format, T0 a { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -545,11 +545,11 @@ public void AppendFormat(ReadOnlySpan format, T0 a { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -650,18 +650,18 @@ public void AppendFormat(ReadOnlySpan format, T0 a if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -678,7 +678,7 @@ public void AppendFormat(ReadOnlySpan format, { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -687,11 +687,11 @@ public void AppendFormat(ReadOnlySpan format, { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -805,18 +805,18 @@ public void AppendFormat(ReadOnlySpan format, if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -833,7 +833,7 @@ public void AppendFormat(ReadOnlySpan form { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -842,11 +842,11 @@ public void AppendFormat(ReadOnlySpan form { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -973,18 +973,18 @@ public void AppendFormat(ReadOnlySpan form if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1001,7 +1001,7 @@ public void AppendFormat(ReadOnlySpan { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1010,11 +1010,11 @@ public void AppendFormat(ReadOnlySpan { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -1154,18 +1154,18 @@ public void AppendFormat(ReadOnlySpan if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1182,7 +1182,7 @@ public void AppendFormat(ReadOnlySpan(ReadOnlySpan(ReadOnlySpan 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1376,7 +1376,7 @@ public void AppendFormat(ReadOnlySp { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1385,11 +1385,11 @@ public void AppendFormat(ReadOnlySp { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -1555,18 +1555,18 @@ public void AppendFormat(ReadOnlySp if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1583,7 +1583,7 @@ public void AppendFormat(ReadO { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1592,11 +1592,11 @@ public void AppendFormat(ReadO { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -1775,18 +1775,18 @@ public void AppendFormat(ReadO if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1803,7 +1803,7 @@ public void AppendFormat( { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1812,11 +1812,11 @@ public void AppendFormat( { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -2008,18 +2008,18 @@ public void AppendFormat( if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2036,7 +2036,7 @@ public void AppendFormat 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2282,7 +2282,7 @@ public void AppendFormat 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); AppendNewLine(); } - public void AppendFormat(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2541,7 +2541,7 @@ public void AppendFormat 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); AppendNewLine(); diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt index 048c5082..2ae0c9ff 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt @@ -28,7 +28,7 @@ namespace Cysharp.Text public ref partial struct Utf8ValueStringBuilder { <# for(var i = 1; i <= 16; i++) { #> - public void AppendFormat<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -45,7 +45,7 @@ namespace Cysharp.Text { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -54,11 +54,11 @@ namespace Cysharp.Text { var size = i - copyFrom; TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, size), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); } // try to find range - var indexParse = FormatParser.Parse(format.Slice(i)); + var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; switch (indexParse.Index) @@ -96,12 +96,12 @@ namespace Cysharp.Text if (copyLength > 0) { TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.Slice(copyFrom, copyLength), buffer.AsSpan(index)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); } } } - public void AppendFormatLine<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + public void AppendFormatLine<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { AppendFormat(format, <#= CreateParameterNames(i) #>); AppendNewLine(); diff --git a/src/ZString/ZString.Format.cs b/src/ZString/ZString.Format.cs index f7c22c5a..dd4b700f 100644 --- a/src/ZString/ZString.Format.cs +++ b/src/ZString/ZString.Format.cs @@ -6,7 +6,7 @@ namespace Cysharp.Text { public static partial class ZString { - public static string Format(ReadOnlySpan format, T0 arg0) + public static string Format(string format, T0 arg0) { var sb = CreateStringBuilder(); try @@ -20,7 +20,7 @@ public static string Format(ReadOnlySpan format, T0 arg0) } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1) + public static string Format(string format, T0 arg0, T1 arg1) { var sb = CreateStringBuilder(); try @@ -34,7 +34,7 @@ public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1) } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) { var sb = CreateStringBuilder(); try @@ -48,7 +48,7 @@ public static string Format(ReadOnlySpan format, T0 arg0, T1 a } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var sb = CreateStringBuilder(); try @@ -62,7 +62,7 @@ public static string Format(ReadOnlySpan format, T0 arg0, } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var sb = CreateStringBuilder(); try @@ -76,7 +76,7 @@ public static string Format(ReadOnlySpan format, T0 ar } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var sb = CreateStringBuilder(); try @@ -90,7 +90,7 @@ public static string Format(ReadOnlySpan format, T } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var sb = CreateStringBuilder(); try @@ -104,7 +104,7 @@ public static string Format(ReadOnlySpan forma } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var sb = CreateStringBuilder(); try @@ -118,7 +118,7 @@ public static string Format(ReadOnlySpan f } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var sb = CreateStringBuilder(); try @@ -132,7 +132,7 @@ public static string Format(ReadOnlySpan(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var sb = CreateStringBuilder(); try @@ -146,7 +146,7 @@ public static string Format(ReadOnlySpan } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var sb = CreateStringBuilder(); try @@ -160,7 +160,7 @@ public static string Format(ReadOnl } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var sb = CreateStringBuilder(); try @@ -174,7 +174,7 @@ public static string Format(Re } } - public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var sb = CreateStringBuilder(); try @@ -188,7 +188,7 @@ public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var sb = CreateStringBuilder(); try @@ -202,7 +202,7 @@ public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var sb = CreateStringBuilder(); try @@ -216,7 +216,7 @@ public static string Format(ReadOnlySpan format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var sb = CreateStringBuilder(); try diff --git a/src/ZString/ZString.Format.tt b/src/ZString/ZString.Format.tt index ef850cf1..277c494b 100644 --- a/src/ZString/ZString.Format.tt +++ b/src/ZString/ZString.Format.tt @@ -30,7 +30,7 @@ namespace Cysharp.Text public static partial class ZString { <# for(var i = 1; i <= 16; i++) { #> - public static string Format<<#= CreateTypeArgument(i) #>>(ReadOnlySpan format, <#= CreateParameters(i) #>) + public static string Format<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { var sb = CreateStringBuilder(); try diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 3526d30b..5965d0a7 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -3,7 +3,7 @@ netstandard2.1;netstandard2.0 Cysharp.Text - + true $(Version) Cysharp @@ -21,6 +21,10 @@ + + + + Utf16ValueStringBuilder.AppendMany.cs diff --git a/src/ZString/_InternalVisibleTo.cs b/src/ZString/_InternalVisibleTo.cs new file mode 100644 index 00000000..dc6e0b1a --- /dev/null +++ b/src/ZString/_InternalVisibleTo.cs @@ -0,0 +1,6 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("ConsoleApp")] +[assembly: InternalsVisibleTo("ConsoleAppNet472")] +[assembly: InternalsVisibleTo("ZString.Tests")] +[assembly: InternalsVisibleTo("ZString.NetCore2Tests")] diff --git a/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj b/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj new file mode 100644 index 00000000..0f797485 --- /dev/null +++ b/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj @@ -0,0 +1,31 @@ + + + + netcoreapp2.1 + false + ZStringTests + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index 3f24879e..4e263175 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -20,4 +20,4 @@ public void EmptyFormat() Test("", 100, 200); } } -} +} \ No newline at end of file diff --git a/tests/ZString.Tests/ZString.Tests.csproj b/tests/ZString.Tests/ZString.Tests.csproj index d9b5bb31..fc5eef7f 100644 --- a/tests/ZString.Tests/ZString.Tests.csproj +++ b/tests/ZString.Tests/ZString.Tests.csproj @@ -1,10 +1,8 @@ - netcoreapp3.1;netcoreapp2.1 - + netcoreapp3.1 false - ZStringTests From 53339b952d08e7f1bf304538a93bdb14d2deb402 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 21:06:26 +0900 Subject: [PATCH 008/139] ci --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 05544968..67c2abec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,12 +18,12 @@ jobs: steps: - checkout - run: dotnet build src/ZString -c Debug - - run: dotnet dotnet test tests/ZString.Tests -c Debug < /dev/null + - run: dotnet test tests/ZString.Tests -c Debug < /dev/null test-netcore2: executor: dotnet2 steps: - checkout - - run: dotnet dotnet test tests/ZString.NetCore2Tests -c Debug < /dev/null + - run: dotnet test tests/ZString.NetCore2Tests -c Debug < /dev/null build-push: executor: dotnet steps: From 40c961fe665871278a72af533d4af277172d72d7 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 21:13:25 +0900 Subject: [PATCH 009/139] comment out 2.1 test --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 67c2abec..801b3c3b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,11 +19,11 @@ jobs: - checkout - run: dotnet build src/ZString -c Debug - run: dotnet test tests/ZString.Tests -c Debug < /dev/null - test-netcore2: - executor: dotnet2 - steps: - - checkout - - run: dotnet test tests/ZString.NetCore2Tests -c Debug < /dev/null +# test-netcore2: +# executor: dotnet2 +# steps: +# - checkout +# - run: dotnet test tests/ZString.NetCore2Tests -c Debug < /dev/null build-push: executor: dotnet steps: From 592181ebbf13c711ffe78231c0a068c1a33840c9 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 22:35:48 +0900 Subject: [PATCH 010/139] unittest ok --- src/ZString/Shims/Shims.cs | 1 + .../Utf16ValueStringBuilder.AppendFormat.cs | 210 ++++- .../Utf16ValueStringBuilder.AppendFormat.tt | 15 +- .../Utf16ValueStringBuilder.AppendMany.cs | 2 +- .../Utf16ValueStringBuilder.AppendMany.tt | 2 +- ...Utf16ValueStringBuilder.CreateFormatter.cs | 2 +- ...Utf16ValueStringBuilder.CreateFormatter.tt | 2 +- ...alueStringBuilder.SpanFormattableAppend.cs | 2 +- ...alueStringBuilder.SpanFormattableAppend.tt | 2 +- src/ZString/Utf16ValueStringBuilder.cs | 24 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 739 +++++++++++------- .../Utf8ValueStringBuilder.AppendFormat.tt | 19 +- .../Utf8/Utf8ValueStringBuilder.AppendMany.cs | 2 +- .../Utf8/Utf8ValueStringBuilder.AppendMany.tt | 2 +- .../Utf8ValueStringBuilder.CreateFormatter.cs | 2 +- .../Utf8ValueStringBuilder.CreateFormatter.tt | 2 +- ...alueStringBuilder.SpanFormattableAppend.cs | 2 +- ...alueStringBuilder.SpanFormattableAppend.tt | 2 +- src/ZString/Utf8ValueStringBuilder.cs | 23 +- src/ZString/ZString.Format.cs | 48 +- src/ZString/ZString.Format.tt | 3 +- src/ZString/ZString.cs | 4 +- tests/ZString.Tests/FormatTest.cs | 61 +- tests/ZString.Tests/Primitives.cs | 209 +++++ 24 files changed, 1053 insertions(+), 327 deletions(-) create mode 100644 tests/ZString.Tests/Primitives.cs diff --git a/src/ZString/Shims/Shims.cs b/src/ZString/Shims/Shims.cs index d1a5764f..c5ed83c3 100644 --- a/src/ZString/Shims/Shims.cs +++ b/src/ZString/Shims/Shims.cs @@ -45,6 +45,7 @@ public static class ShimsExtensions { public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) { + if (span.Length == 0) return 0; fixed (char* src = span) fixed (byte* dest = bytes) { diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 76f1cc3a..5182c93b 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -2,7 +2,7 @@ namespace Cysharp.Text { - public ref partial struct Utf16ValueStringBuilder + public partial struct Utf16ValueStringBuilder { public void AppendFormat(string format, T0 arg0) { @@ -61,6 +61,19 @@ public void AppendFormat(string format, T0 arg0) ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -154,6 +167,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -260,6 +286,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -379,6 +418,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -511,6 +563,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -656,6 +721,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -814,6 +892,19 @@ public void AppendFormat(string format, T0 arg0, T1 ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -985,6 +1076,19 @@ public void AppendFormat(string format, T0 arg0, ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -1169,6 +1273,19 @@ public void AppendFormat(string format, T0 a ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -1366,6 +1483,19 @@ public void AppendFormat(string format, ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -1576,6 +1706,19 @@ public void AppendFormat(string for ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -1799,6 +1942,19 @@ public void AppendFormat(strin ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -2035,6 +2191,19 @@ public void AppendFormat( ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; @@ -2284,6 +2453,19 @@ public void AppendFormat public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) @@ -87,6 +87,19 @@ namespace Cysharp.Text ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } NEXT_LOOP: continue; diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs index be38d681..e900deb4 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs @@ -2,7 +2,7 @@ namespace Cysharp.Text { - public ref partial struct Utf16ValueStringBuilder + public partial struct Utf16ValueStringBuilder { public void AppendMany(T0 arg0, T1 arg1) { diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt index f100c7f9..e6f3a703 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt @@ -25,7 +25,7 @@ using System; namespace Cysharp.Text { - public ref partial struct Utf16ValueStringBuilder + public partial struct Utf16ValueStringBuilder { <# for(var i = 2; i <= 16; i++) { #> public void AppendMany<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 63c24893..54a422d6 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -2,7 +2,7 @@ namespace Cysharp.Text { - public ref partial struct Utf16ValueStringBuilder + public partial struct Utf16ValueStringBuilder { static object CreateFormatter(Type type) { diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt index 52591086..b9947816 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt @@ -29,7 +29,7 @@ using System; namespace Cysharp.Text { - public ref partial struct Utf16ValueStringBuilder + public partial struct Utf16ValueStringBuilder { static object CreateFormatter(Type type) { diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index f2713cd5..0c7eaad5 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -3,7 +3,7 @@ namespace Cysharp.Text { - public ref partial struct Utf16ValueStringBuilder + public partial struct Utf16ValueStringBuilder { [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt index 6233dd6a..7776e1a4 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt @@ -30,7 +30,7 @@ using System.Runtime.CompilerServices; namespace Cysharp.Text { - public ref partial struct Utf16ValueStringBuilder + public partial struct Utf16ValueStringBuilder { <# foreach(var t in spanFormattables) { #> [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index fb6b3a2c..189383a4 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -4,10 +4,11 @@ namespace Cysharp.Text { - public ref partial struct Utf16ValueStringBuilder + public partial struct Utf16ValueStringBuilder : IDisposable { public delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); + const int ThreadStaticBufferSize = 31111; const int DefaultBufferSize = 32768; // use 32K default buffer. static char newLine1; @@ -43,13 +44,20 @@ static Utf16ValueStringBuilder() public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); - - internal void Init() + internal void Init(bool disposeImmediately) { - var buf = scratchBuffer; - if (buf == null) + char[] buf; + if (disposeImmediately) + { + buf = scratchBuffer; + if (buf == null) + { + buf = scratchBuffer = new char[ThreadStaticBufferSize]; + } + } + else { - buf = scratchBuffer = new char[DefaultBufferSize]; + buf = ArrayPool.Shared.Rent(DefaultBufferSize); } buffer = buf; @@ -58,7 +66,7 @@ internal void Init() public void Dispose() { - if (buffer.Length != DefaultBufferSize) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } @@ -85,7 +93,7 @@ void Grow(int sizeHint = 0) var newBuffer = ArrayPool.Shared.Rent(nextSize); buffer.CopyTo(newBuffer, 0); - if (buffer.Length != DefaultBufferSize) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index 9e928305..334abc75 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -1,8 +1,9 @@ using System; +using System.Buffers; namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder { public void AppendFormat(string format, T0 arg0) { @@ -37,14 +38,15 @@ public void AppendFormat(string format, T0 arg0) var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -59,6 +61,17 @@ public void AppendFormat(string format, T0 arg0) ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -114,14 +127,15 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -131,10 +145,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -149,6 +163,17 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -204,14 +229,15 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -221,10 +247,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -234,10 +260,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -252,6 +278,17 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -307,14 +344,15 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -324,10 +362,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -337,10 +375,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -350,10 +388,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -368,6 +406,17 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -423,14 +472,15 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -440,10 +490,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -453,10 +503,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -466,10 +516,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -479,10 +529,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -497,6 +547,17 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -552,14 +613,15 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -569,10 +631,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -582,10 +644,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -595,10 +657,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -608,10 +670,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -621,10 +683,10 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } case 5: { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -639,6 +701,17 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -694,14 +767,15 @@ public void AppendFormat(string format, T0 arg0, T1 var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -711,10 +785,10 @@ public void AppendFormat(string format, T0 arg0, T1 } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -724,10 +798,10 @@ public void AppendFormat(string format, T0 arg0, T1 } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -737,10 +811,10 @@ public void AppendFormat(string format, T0 arg0, T1 } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -750,10 +824,10 @@ public void AppendFormat(string format, T0 arg0, T1 } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -763,10 +837,10 @@ public void AppendFormat(string format, T0 arg0, T1 } case 5: { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -776,10 +850,10 @@ public void AppendFormat(string format, T0 arg0, T1 } case 6: { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -794,6 +868,17 @@ public void AppendFormat(string format, T0 arg0, T1 ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -849,14 +934,15 @@ public void AppendFormat(string format, T0 arg0, var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -866,10 +952,10 @@ public void AppendFormat(string format, T0 arg0, } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -879,10 +965,10 @@ public void AppendFormat(string format, T0 arg0, } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -892,10 +978,10 @@ public void AppendFormat(string format, T0 arg0, } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -905,10 +991,10 @@ public void AppendFormat(string format, T0 arg0, } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -918,10 +1004,10 @@ public void AppendFormat(string format, T0 arg0, } case 5: { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -931,10 +1017,10 @@ public void AppendFormat(string format, T0 arg0, } case 6: { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -944,10 +1030,10 @@ public void AppendFormat(string format, T0 arg0, } case 7: { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -962,6 +1048,17 @@ public void AppendFormat(string format, T0 arg0, ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -1017,14 +1114,15 @@ public void AppendFormat(string format, T0 a var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -1034,10 +1132,10 @@ public void AppendFormat(string format, T0 a } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -1047,10 +1145,10 @@ public void AppendFormat(string format, T0 a } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -1060,10 +1158,10 @@ public void AppendFormat(string format, T0 a } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -1073,10 +1171,10 @@ public void AppendFormat(string format, T0 a } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -1086,10 +1184,10 @@ public void AppendFormat(string format, T0 a } case 5: { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -1099,10 +1197,10 @@ public void AppendFormat(string format, T0 a } case 6: { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -1112,10 +1210,10 @@ public void AppendFormat(string format, T0 a } case 7: { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -1125,10 +1223,10 @@ public void AppendFormat(string format, T0 a } case 8: { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); } @@ -1143,6 +1241,17 @@ public void AppendFormat(string format, T0 a ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -1198,14 +1307,15 @@ public void AppendFormat(string format, var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -1215,10 +1325,10 @@ public void AppendFormat(string format, } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -1228,10 +1338,10 @@ public void AppendFormat(string format, } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -1241,10 +1351,10 @@ public void AppendFormat(string format, } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -1254,10 +1364,10 @@ public void AppendFormat(string format, } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -1267,10 +1377,10 @@ public void AppendFormat(string format, } case 5: { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -1280,10 +1390,10 @@ public void AppendFormat(string format, } case 6: { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -1293,10 +1403,10 @@ public void AppendFormat(string format, } case 7: { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -1306,10 +1416,10 @@ public void AppendFormat(string format, } case 8: { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); } @@ -1319,10 +1429,10 @@ public void AppendFormat(string format, } case 9: { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); } @@ -1337,6 +1447,17 @@ public void AppendFormat(string format, ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -1392,14 +1513,15 @@ public void AppendFormat(string for var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -1409,10 +1531,10 @@ public void AppendFormat(string for } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -1422,10 +1544,10 @@ public void AppendFormat(string for } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -1435,10 +1557,10 @@ public void AppendFormat(string for } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -1448,10 +1570,10 @@ public void AppendFormat(string for } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -1461,10 +1583,10 @@ public void AppendFormat(string for } case 5: { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -1474,10 +1596,10 @@ public void AppendFormat(string for } case 6: { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -1487,10 +1609,10 @@ public void AppendFormat(string for } case 7: { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -1500,10 +1622,10 @@ public void AppendFormat(string for } case 8: { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); } @@ -1513,10 +1635,10 @@ public void AppendFormat(string for } case 9: { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); } @@ -1526,10 +1648,10 @@ public void AppendFormat(string for } case 10: { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); } @@ -1544,6 +1666,17 @@ public void AppendFormat(string for ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -1599,14 +1732,15 @@ public void AppendFormat(strin var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -1616,10 +1750,10 @@ public void AppendFormat(strin } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -1629,10 +1763,10 @@ public void AppendFormat(strin } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -1642,10 +1776,10 @@ public void AppendFormat(strin } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -1655,10 +1789,10 @@ public void AppendFormat(strin } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -1668,10 +1802,10 @@ public void AppendFormat(strin } case 5: { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -1681,10 +1815,10 @@ public void AppendFormat(strin } case 6: { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -1694,10 +1828,10 @@ public void AppendFormat(strin } case 7: { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -1707,10 +1841,10 @@ public void AppendFormat(strin } case 8: { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); } @@ -1720,10 +1854,10 @@ public void AppendFormat(strin } case 9: { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); } @@ -1733,10 +1867,10 @@ public void AppendFormat(strin } case 10: { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); } @@ -1746,10 +1880,10 @@ public void AppendFormat(strin } case 11: { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); } @@ -1764,6 +1898,17 @@ public void AppendFormat(strin ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -1819,14 +1964,15 @@ public void AppendFormat( var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -1836,10 +1982,10 @@ public void AppendFormat( } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -1849,10 +1995,10 @@ public void AppendFormat( } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -1862,10 +2008,10 @@ public void AppendFormat( } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -1875,10 +2021,10 @@ public void AppendFormat( } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -1888,10 +2034,10 @@ public void AppendFormat( } case 5: { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -1901,10 +2047,10 @@ public void AppendFormat( } case 6: { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -1914,10 +2060,10 @@ public void AppendFormat( } case 7: { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -1927,10 +2073,10 @@ public void AppendFormat( } case 8: { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); } @@ -1940,10 +2086,10 @@ public void AppendFormat( } case 9: { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); } @@ -1953,10 +2099,10 @@ public void AppendFormat( } case 10: { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); } @@ -1966,10 +2112,10 @@ public void AppendFormat( } case 11: { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); } @@ -1979,10 +2125,10 @@ public void AppendFormat( } case 12: { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); } @@ -1997,6 +2143,17 @@ public void AppendFormat( ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; @@ -2052,14 +2209,15 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -2069,10 +2227,10 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -2082,10 +2240,10 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -2095,10 +2253,10 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -2108,10 +2266,10 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -2121,10 +2279,10 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -2134,10 +2292,10 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -2147,10 +2305,10 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -2160,10 +2318,10 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); } @@ -2173,10 +2331,10 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); } @@ -2186,10 +2344,10 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); } @@ -2199,10 +2357,10 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); } @@ -2212,10 +2370,10 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); } @@ -2225,10 +2383,10 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); } @@ -2243,6 +2401,17 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -2315,10 +2485,10 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -2328,10 +2498,10 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -2341,10 +2511,10 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -2354,10 +2524,10 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -2367,10 +2537,10 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -2380,10 +2550,10 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -2393,10 +2563,10 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -2406,10 +2576,10 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); } @@ -2419,10 +2589,10 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); } @@ -2432,10 +2602,10 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); } @@ -2445,10 +2615,10 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); } @@ -2458,10 +2628,10 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); } @@ -2471,10 +2641,10 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); } @@ -2484,10 +2654,10 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg14)); } @@ -2502,6 +2672,17 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); } @@ -2574,10 +2756,10 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); } @@ -2587,10 +2769,10 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); } @@ -2600,10 +2782,10 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); } @@ -2613,10 +2795,10 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); } @@ -2626,10 +2808,10 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); } @@ -2639,10 +2821,10 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); } @@ -2652,10 +2834,10 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); } @@ -2665,10 +2847,10 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); } @@ -2678,10 +2860,10 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); } @@ -2691,10 +2873,10 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); } @@ -2704,10 +2886,10 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); } @@ -2717,10 +2899,10 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); } @@ -2730,10 +2912,10 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); } @@ -2743,10 +2925,10 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg14)); } @@ -2756,10 +2938,10 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg15)); } @@ -2774,6 +2956,17 @@ public void AppendFormat using System; +using System.Buffers; namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder { <# for(var i = 1; i <= 16; i++) { #> public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) @@ -61,15 +62,16 @@ namespace Cysharp.Text var indexParse = FormatParser.Parse(format.AsSpan(i)); copyFrom = i + indexParse.LastIndex + 1; i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { <# for(var j = 0; j < i; j++) { #> case <#= j #>: { - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out var written, default)) + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out var written, writeFormat)) { Grow(); - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg<#= j #>)); } @@ -85,6 +87,17 @@ namespace Cysharp.Text ThrowFormatException(); } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } NEXT_LOOP: continue; diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs index ffed9b4e..30b9f992 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs @@ -2,7 +2,7 @@ namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder { public void AppendMany(T0 arg0, T1 arg1) { diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt index 779ecaa2..a3dbe717 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt @@ -25,7 +25,7 @@ using System; namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder { <# for(var i = 2; i <= 16; i++) { #> public void AppendMany<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index 2931b87e..7511ae11 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -4,7 +4,7 @@ namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder { static object CreateFormatter(Type type) { diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt index e90e54d0..b82d6ef9 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt @@ -31,7 +31,7 @@ using System.Buffers.Text; namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder { static object CreateFormatter(Type type) { diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index 2ea32b05..bcf2135c 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -5,7 +5,7 @@ namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder { [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt index c260b9c8..86330736 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt @@ -32,7 +32,7 @@ using System.Runtime.CompilerServices; namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder { <# foreach(var t in spanFormattables) { #> [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index ef18b01a..522e53c4 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -7,10 +7,11 @@ namespace Cysharp.Text { - public ref partial struct Utf8ValueStringBuilder + public partial struct Utf8ValueStringBuilder : IDisposable { public delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); + const int ThreadStaticBufferSize = 64444; const int DefaultBufferSize = 65536; // use 64K default buffer. static Encoding UTF8NoBom = new UTF8Encoding(false); @@ -45,12 +46,20 @@ static Utf8ValueStringBuilder() public int Length => index; public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); - internal void Init() + internal void Init(bool disposeImmediately) { - var buf = scratchBuffer; - if (buf == null) + byte[] buf; + if (disposeImmediately) { - buf = scratchBuffer = new byte[DefaultBufferSize]; + buf = scratchBuffer; + if (buf == null) + { + buf = scratchBuffer = new byte[ThreadStaticBufferSize]; + } + } + else + { + buf = ArrayPool.Shared.Rent(DefaultBufferSize); } buffer = buf; @@ -59,7 +68,7 @@ internal void Init() public void Dispose() { - if (buffer.Length != DefaultBufferSize) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } @@ -86,7 +95,7 @@ void Grow(int sizeHint = 0) var newBuffer = ArrayPool.Shared.Rent(nextSize); buffer.CopyTo(newBuffer, 0); - if (buffer.Length != DefaultBufferSize) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } diff --git a/src/ZString/ZString.Format.cs b/src/ZString/ZString.Format.cs index dd4b700f..2139423b 100644 --- a/src/ZString/ZString.Format.cs +++ b/src/ZString/ZString.Format.cs @@ -8,7 +8,8 @@ public static partial class ZString { public static string Format(string format, T0 arg0) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0); @@ -22,7 +23,8 @@ public static string Format(string format, T0 arg0) public static string Format(string format, T0 arg0, T1 arg1) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1); @@ -36,7 +38,8 @@ public static string Format(string format, T0 arg0, T1 arg1) public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2); @@ -50,7 +53,8 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2 public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3); @@ -64,7 +68,8 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); @@ -78,7 +83,8 @@ public static string Format(string format, T0 arg0, T1 arg1, public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); @@ -92,7 +98,8 @@ public static string Format(string format, T0 arg0, T1 a public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); @@ -106,7 +113,8 @@ public static string Format(string format, T0 arg0, public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); @@ -120,7 +128,8 @@ public static string Format(string format, T0 ar public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); @@ -134,7 +143,8 @@ public static string Format(string format, T public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); @@ -148,7 +158,8 @@ public static string Format(string forma public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); @@ -162,7 +173,8 @@ public static string Format(string public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); @@ -176,7 +188,8 @@ public static string Format(st public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); @@ -190,7 +203,8 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); @@ -204,7 +218,8 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); @@ -218,7 +233,8 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); diff --git a/src/ZString/ZString.Format.tt b/src/ZString/ZString.Format.tt index 277c494b..16746f37 100644 --- a/src/ZString/ZString.Format.tt +++ b/src/ZString/ZString.Format.tt @@ -32,7 +32,8 @@ namespace Cysharp.Text <# for(var i = 1; i <= 16; i++) { #> public static string Format<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { - var sb = CreateStringBuilder(); + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); try { sb.AppendFormat(format, <#= CreateParameterNames(i) #>); diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 3d9704c4..788cbaed 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -5,14 +5,14 @@ public static partial class ZString public static Utf16ValueStringBuilder CreateStringBuilder() { var builder = new Utf16ValueStringBuilder(); - builder.Init(); + builder.Init(false); return builder; } public static Utf8ValueStringBuilder CreateUtf8StringBuilder() { var builder = new Utf8ValueStringBuilder(); - builder.Init(); + builder.Init(false); return builder; } } diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index 4e263175..052ec015 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -9,9 +9,18 @@ public class FormatTest { void Test(string format, T0 t0, T1 t1) { - var actual = ZString.Format(format, t0, t1); - var expected = string.Format(format, t0, t1); - actual.Should().Be(expected); + { + var actual = ZString.Format(format, t0, t1); + var expected = string.Format(format, t0, t1); + actual.Should().Be(expected); + } + { + var sb = ZString.CreateUtf8StringBuilder(); + sb.AppendFormat(format, t0, t1); + var actual = sb.ToString(); + var expected = string.Format(format, t0, t1); + actual.Should().Be(expected); + } } [Fact] @@ -19,5 +28,51 @@ public void EmptyFormat() { Test("", 100, 200); } + + [Fact] + public void NoFormat() + { + Test("abcdefg", 100, 200); + } + + [Fact] + public void SingleFormat() + { + Test("{0}", 100, 200); + } + + [Fact] + public void DoubleFormat() + { + Test("{0}{1}", 100, 200); + } + + [Fact] + public void DoubleFormat2() + { + Test("abc{0}def{1}", 100, 200); + } + + [Fact] + public void DoubleFormat3() + { + Test("abc{0}def{1}ghi", 100, 200); + } + + [Fact] + public void Comment() + { + Test("abc{{0}}def{1}ghi", 100, 200); + } + + [Fact] + public void FormatArgs() + { +#if NETCOREAPP3_1 + ZString.Format("{0:00000000}-{1:00000000}", 100, 200).Should().Be("00000100-00000200"); +#else + ZString.Format("{0:00000000}-{1:00000000}", 100, 200).Should().Be("100-200"); +#endif + } } } \ No newline at end of file diff --git a/tests/ZString.Tests/Primitives.cs b/tests/ZString.Tests/Primitives.cs new file mode 100644 index 00000000..8f65166c --- /dev/null +++ b/tests/ZString.Tests/Primitives.cs @@ -0,0 +1,209 @@ +using Cysharp.Text; +using FluentAssertions; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public enum MoreMyEnum + { + Fruit, Apple, Orange + } + + public class Primitives + { + [Theory] + [InlineData(int.MinValue, int.MinValue)] + [InlineData(0, -1)] + [InlineData(-1, 1)] + [InlineData(-12, 12)] + [InlineData(-123, 123)] + [InlineData(-1234, 1234)] + [InlineData(-12345, 12345)] + [InlineData(-123456, 123456)] + [InlineData(-1234567, 1234567)] + [InlineData(-12345678, 12345678)] + [InlineData(-123456789, 123456789)] + [InlineData(-1234567890, 1234567890)] + public void Integer(int x, int y) + { + using (var sb1 = ZString.CreateStringBuilder()) + using (var sb2 = ZString.CreateUtf8StringBuilder()) + using (var sb3 = ZString.CreateStringBuilder()) + using (var sb4 = ZString.CreateUtf8StringBuilder()) + { + var sb5 = new StringBuilder(); + sb1.Append(x); sb1.Append(y); + sb2.Append(x); sb2.Append(y); + sb3.AppendMany(x, y); + sb4.AppendMany(x, y); + sb5.Append(x); sb5.Append(y); + + sb1.ToString().Should().Be(sb2.ToString()); + sb1.ToString().Should().Be(sb3.ToString()); + sb1.ToString().Should().Be(sb4.ToString()); + sb1.ToString().Should().Be(sb5.ToString()); + } + } + + [Theory] + [InlineData(ulong.MinValue, ulong.MinValue)] + [InlineData(0UL, 1UL)] + [InlineData(1UL, 1UL)] + [InlineData(12UL, 12UL)] + [InlineData(123UL, 123UL)] + [InlineData(1234UL, 1234UL)] + [InlineData(12345UL, 12345UL)] + [InlineData(123456UL, 123456UL)] + [InlineData(1234567UL, 1234567UL)] + [InlineData(12345678UL, 12345678UL)] + [InlineData(123456789UL, 123456789UL)] + [InlineData(1234567890UL, 1234567890UL)] + [InlineData(12345678901UL, 12345678901UL)] + [InlineData(123456789012UL, 123456789012UL)] + public void UInt64(ulong x, ulong y) + { + using (var sb1 = ZString.CreateStringBuilder()) + using (var sb2 = ZString.CreateUtf8StringBuilder()) + using (var sb3 = ZString.CreateStringBuilder()) + using (var sb4 = ZString.CreateUtf8StringBuilder()) + { + var sb5 = new StringBuilder(); + sb1.Append(x); sb1.Append(y); + sb2.Append(x); sb2.Append(y); + sb3.AppendMany(x, y); + sb4.AppendMany(x, y); + sb5.Append(x); sb5.Append(y); + + sb1.ToString().Should().Be(sb2.ToString()); + sb1.ToString().Should().Be(sb3.ToString()); + sb1.ToString().Should().Be(sb4.ToString()); + sb1.ToString().Should().Be(sb5.ToString()); + } + } + + [Theory] + //[InlineData(double.MinValue, double.MinValue)] + //[InlineData(double.Epsilon, double.NaN)] + [InlineData(0.1, -0.1)] + [InlineData(0.0, 0.0)] + [InlineData(0.12, 0.12)] + [InlineData(0.123, 0.123)] + [InlineData(0.1234, 0.1234)] + [InlineData(0.12345, 0.12345)] + [InlineData(1.12345, 1.12345)] + [InlineData(12.12345, 12.12345)] + [InlineData(123.12345, 123.12345)] + [InlineData(1234.12345, 1234.12345)] + [InlineData(12345.12345, 12345.12345)] + [InlineData(1234512345d, 1234512345d)] + public void Double(double x, double y) + { + using (var sb1 = ZString.CreateStringBuilder()) + using (var sb2 = ZString.CreateUtf8StringBuilder()) + using (var sb3 = ZString.CreateStringBuilder()) + using (var sb4 = ZString.CreateUtf8StringBuilder()) + { + var sb5 = new StringBuilder(); + sb1.Append(x); sb1.Append(y); + sb2.Append(x); sb2.Append(y); + sb3.AppendMany(x, y); + sb4.AppendMany(x, y); + sb5.Append(x); sb5.Append(y); + + sb1.ToString().Should().Be(sb2.ToString()); + sb1.ToString().Should().Be(sb3.ToString()); + sb1.ToString().Should().Be(sb4.ToString()); + sb1.ToString().Should().Be(sb5.ToString()); + } + } + + [Theory] + //[InlineData(double.MinValue, double.MinValue)] + //[InlineData(double.Epsilon, double.NaN)] + [InlineData(0.1f, -0.1f)] + [InlineData(0.0f, 0.0f)] + [InlineData(0.12f, 0.12f)] + [InlineData(0.123f, 0.123f)] + [InlineData(0.1234f, 0.1234f)] + [InlineData(0.12345f, 0.12345f)] + [InlineData(1.12345f, 1.12345f)] + [InlineData(12.12345f, 12.12345f)] + [InlineData(123.123f, 123.123f)] + public void Single(float x, float y) + { + using (var sb1 = ZString.CreateStringBuilder()) + using (var sb2 = ZString.CreateUtf8StringBuilder()) + using (var sb3 = ZString.CreateStringBuilder()) + using (var sb4 = ZString.CreateUtf8StringBuilder()) + { + var sb5 = new StringBuilder(); + sb1.Append(x); sb1.Append(y); + sb2.Append(x); sb2.Append(y); + sb3.AppendMany(x, y); + sb4.AppendMany(x, y); + sb5.Append(x); sb5.Append(y); + + sb1.ToString().Should().Be(sb2.ToString()); + sb1.ToString().Should().Be(sb3.ToString()); + sb1.ToString().Should().Be(sb4.ToString()); + sb1.ToString().Should().Be(sb5.ToString()); + } + } + + [Fact] + public void Others() + { + using (var sb1 = ZString.CreateStringBuilder()) + //using (var sb2 = ZString.CreateUtf8StringBuilder()) + using (var sb3 = ZString.CreateStringBuilder()) + //using (var sb4 = ZString.CreateUtf8StringBuilder()) + { + var x = DateTime.Now; + var y = DateTimeOffset.Now; + var z = TimeSpan.FromMilliseconds(12345.6789); + var g = Guid.NewGuid(); + + var sb5 = new StringBuilder(); + sb1.Append(x); sb1.Append(y); sb1.Append(z); sb1.Append(g); + //sb2.Append(x, StandardFormat.Parse("O")); sb2.Append(y, StandardFormat.Parse("O")); sb2.Append(z); sb2.Append(g); + sb3.AppendMany(x, y, z, g); + //sb4.AppendMany(x, y, z, g); + sb5.Append(x); sb5.Append(y); sb5.Append(z); sb5.Append(g); + + //sb1.ToString().Should().Be(sb2.ToString()); + sb1.ToString().Should().Be(sb3.ToString()); + //sb1.ToString().Should().Be(sb4.ToString()); + sb1.ToString().Should().Be(sb5.ToString()); + } + } + + [Fact] + public void EnumTest() + { + var x = MoreMyEnum.Apple; + var y = MoreMyEnum.Orange; + + using (var sb1 = ZString.CreateStringBuilder()) + using (var sb2 = ZString.CreateUtf8StringBuilder()) + using (var sb3 = ZString.CreateStringBuilder()) + using (var sb4 = ZString.CreateUtf8StringBuilder()) + { + var sb5 = new StringBuilder(); + sb1.Append(x); sb1.Append(y); + sb2.Append(x); sb2.Append(y); + sb3.AppendMany(x, y); + sb4.AppendMany(x, y); + sb5.Append(x); sb5.Append(y); + + sb1.ToString().Should().Be(sb2.ToString()); + sb1.ToString().Should().Be(sb3.ToString()); + sb1.ToString().Should().Be(sb4.ToString()); + sb1.ToString().Should().Be(sb5.ToString()); + } + } + } +} From d548c6fc6f9adf6cea94a605edc9d4debcc3f425 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 23:20:28 +0900 Subject: [PATCH 011/139] Unity --- .gitignore | 6 +- src/ZString.Unity/Assets/Plugins.meta | 8 + .../Assets/Plugins/System.Buffers.dll | Bin 0 -> 28304 bytes .../Assets/Plugins/System.Buffers.dll.meta | 33 + .../Assets/Plugins/System.Memory.dll | Bin 0 -> 148760 bytes .../Assets/Plugins/System.Memory.dll.meta | 33 + ...System.Runtime.CompilerServices.Unsafe.dll | Bin 0 -> 16968 bytes ...m.Runtime.CompilerServices.Unsafe.dll.meta | 33 + src/ZString.Unity/Assets/Scenes.meta | 8 + .../Assets/Scenes/SampleScene.unity | 188 + .../Assets/Scenes/SampleScene.unity.meta | 7 + src/ZString.Unity/Assets/Scenes/Test.cs | 1 + src/ZString.Unity/Assets/Scenes/Test.cs.meta | 11 + src/ZString.Unity/Assets/Scripts.meta | 8 + src/ZString.Unity/Assets/Scripts/Editor.meta | 8 + .../Assets/Scripts/Editor/PackageExporter.cs | 43 + .../Scripts/Editor/PackageExporter.cs.meta | 11 + src/ZString.Unity/Assets/Scripts/ZString.meta | 8 + .../Assets/Scripts/ZString/EnumUtil.cs | 48 + .../Assets/Scripts/ZString/EnumUtil.cs.meta | 11 + .../Assets/Scripts/ZString/FormatParser.cs | 55 + .../Scripts/ZString/FormatParser.cs.meta | 11 + .../Assets/Scripts/ZString/Shims.meta | 8 + .../ZString/Shims/DoubleConversion.meta | 8 + .../ZString/Shims/DoubleConversion/DiyFp.cs | 123 + .../Shims/DoubleConversion/DiyFp.cs.meta | 11 + .../DoubleToStringConverter.cs | 890 +++++ .../DoubleToStringConverter.cs.meta | 11 + .../ZString/Shims/DoubleConversion/IEEE.cs | 441 +++ .../Shims/DoubleConversion/IEEE.cs.meta | 11 + .../DoubleConversion/PowersOfTenCache.cs | 154 + .../DoubleConversion/PowersOfTenCache.cs.meta | 11 + .../Shims/DoubleConversion/StringToDouble.cs | 535 +++ .../DoubleConversion/StringToDouble.cs.meta | 11 + .../StringToDoubleConverter.cs | 625 ++++ .../StringToDoubleConverter.cs.meta | 11 + .../Assets/Scripts/ZString/Shims/Shims.cs | 483 +++ .../Scripts/ZString/Shims/Shims.cs.meta | 11 + .../Assets/Scripts/ZString/Unity.meta | 8 + .../ZString/Unity/TextMeshProExtensions.cs | 185 + .../Unity/TextMeshProExtensions.cs.meta | 11 + .../Assets/Scripts/ZString/Utf16.meta | 8 + .../Utf16ValueStringBuilder.AppendFormat.cs | 3056 +++++++++++++++++ ...f16ValueStringBuilder.AppendFormat.cs.meta | 11 + .../Utf16ValueStringBuilder.AppendMany.cs | 1538 +++++++++ ...Utf16ValueStringBuilder.AppendMany.cs.meta | 11 + ...Utf16ValueStringBuilder.CreateFormatter.cs | 73 + ...ValueStringBuilder.CreateFormatter.cs.meta | 11 + ...alueStringBuilder.SpanFormattableAppend.cs | 429 +++ ...tringBuilder.SpanFormattableAppend.cs.meta | 11 + .../ZString/Utf16ValueStringBuilder.cs | 249 ++ .../ZString/Utf16ValueStringBuilder.cs.meta | 11 + .../Assets/Scripts/ZString/Utf8.meta | 8 + .../Utf8ValueStringBuilder.AppendFormat.cs | 2993 ++++++++++++++++ ...tf8ValueStringBuilder.AppendFormat.cs.meta | 11 + .../Utf8/Utf8ValueStringBuilder.AppendMany.cs | 1538 +++++++++ .../Utf8ValueStringBuilder.AppendMany.cs.meta | 11 + .../Utf8ValueStringBuilder.CreateFormatter.cs | 75 + ...ValueStringBuilder.CreateFormatter.cs.meta | 11 + ...alueStringBuilder.SpanFormattableAppend.cs | 431 +++ ...tringBuilder.SpanFormattableAppend.cs.meta | 11 + .../Scripts/ZString/Utf8ValueStringBuilder.cs | 263 ++ .../ZString/Utf8ValueStringBuilder.cs.meta | 11 + .../Assets/Scripts/ZString/ZString.Format.cs | 250 ++ .../Scripts/ZString/ZString.Format.cs.meta | 11 + .../Assets/Scripts/ZString/ZString.asmdef | 14 + .../Scripts/ZString/ZString.asmdef.meta | 7 + .../Assets/Scripts/ZString/ZString.cs | 19 + .../Assets/Scripts/ZString/ZString.cs.meta | 11 + .../ProjectSettings/AudioManager.asset | 17 + .../ProjectSettings/ClusterInputManager.asset | 6 + .../ProjectSettings/DynamicsManager.asset | 30 + .../ProjectSettings/EditorBuildSettings.asset | 11 + .../ProjectSettings/EditorSettings.asset | 21 + .../ProjectSettings/GraphicsSettings.asset | 57 + .../ProjectSettings/InputManager.asset | 295 ++ .../ProjectSettings/NavMeshAreas.asset | 91 + .../ProjectSettings/NetworkManager.asset | 8 + .../ProjectSettings/Physics2DSettings.asset | Bin 0 -> 4448 bytes .../ProjectSettings/PresetManager.asset | 6 + .../ProjectSettings/ProjectSettings.asset | 619 ++++ .../ProjectSettings/ProjectVersion.txt | 2 + .../ProjectSettings/QualitySettings.asset | 191 ++ .../ProjectSettings/TagManager.asset | 43 + .../ProjectSettings/TimeManager.asset | 9 + .../UnityConnectSettings.asset | 34 + .../ProjectSettings/VFXManager.asset | 7 + .../ProjectSettings/XRSettings.asset | 10 + .../DoubleToStringConverter.cs | 2 +- src/ZString/Shims/Shims.cs | 2 +- src/ZString/Unity/TextMeshProExtensions.cs | 185 + src/ZString/Unity/TextMeshProExtensions.tt | 45 + src/ZString/ZString.csproj | 17 + 93 files changed, 16867 insertions(+), 3 deletions(-) create mode 100644 src/ZString.Unity/Assets/Plugins.meta create mode 100644 src/ZString.Unity/Assets/Plugins/System.Buffers.dll create mode 100644 src/ZString.Unity/Assets/Plugins/System.Buffers.dll.meta create mode 100644 src/ZString.Unity/Assets/Plugins/System.Memory.dll create mode 100644 src/ZString.Unity/Assets/Plugins/System.Memory.dll.meta create mode 100644 src/ZString.Unity/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll create mode 100644 src/ZString.Unity/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll.meta create mode 100644 src/ZString.Unity/Assets/Scenes.meta create mode 100644 src/ZString.Unity/Assets/Scenes/SampleScene.unity create mode 100644 src/ZString.Unity/Assets/Scenes/SampleScene.unity.meta create mode 100644 src/ZString.Unity/Assets/Scenes/Test.cs create mode 100644 src/ZString.Unity/Assets/Scenes/Test.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts.meta create mode 100644 src/ZString.Unity/Assets/Scripts/Editor.meta create mode 100644 src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs create mode 100644 src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Unity.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.cs.meta create mode 100644 src/ZString.Unity/ProjectSettings/AudioManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/ClusterInputManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/DynamicsManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/EditorBuildSettings.asset create mode 100644 src/ZString.Unity/ProjectSettings/EditorSettings.asset create mode 100644 src/ZString.Unity/ProjectSettings/GraphicsSettings.asset create mode 100644 src/ZString.Unity/ProjectSettings/InputManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/NavMeshAreas.asset create mode 100644 src/ZString.Unity/ProjectSettings/NetworkManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/Physics2DSettings.asset create mode 100644 src/ZString.Unity/ProjectSettings/PresetManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/ProjectSettings.asset create mode 100644 src/ZString.Unity/ProjectSettings/ProjectVersion.txt create mode 100644 src/ZString.Unity/ProjectSettings/QualitySettings.asset create mode 100644 src/ZString.Unity/ProjectSettings/TagManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/TimeManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/UnityConnectSettings.asset create mode 100644 src/ZString.Unity/ProjectSettings/VFXManager.asset create mode 100644 src/ZString.Unity/ProjectSettings/XRSettings.asset create mode 100644 src/ZString/Unity/TextMeshProExtensions.cs create mode 100644 src/ZString/Unity/TextMeshProExtensions.tt diff --git a/.gitignore b/.gitignore index f79f9627..67a15a7f 100644 --- a/.gitignore +++ b/.gitignore @@ -116,4 +116,8 @@ nuget/tools/* # Unity Library/ -Temp/ \ No newline at end of file +Temp/ +src/ZString.Unity/Assembly-CSharp.csproj +src/ZString.Unity/Assembly-CSharp-Editor.csproj +src/ZString.Unity/ZString.csproj +src/ZString.Unity/ZString.Unity.sln diff --git a/src/ZString.Unity/Assets/Plugins.meta b/src/ZString.Unity/Assets/Plugins.meta new file mode 100644 index 00000000..839240a4 --- /dev/null +++ b/src/ZString.Unity/Assets/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7ddd3a1ff295f1440982cd97100549a7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Plugins/System.Buffers.dll b/src/ZString.Unity/Assets/Plugins/System.Buffers.dll new file mode 100644 index 0000000000000000000000000000000000000000..c517a3b62cc7e190fb347c00a960311a9349b53c GIT binary patch literal 28304 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 literal 0 HcmV?d00001 diff --git a/src/ZString.Unity/Assets/Plugins/System.Buffers.dll.meta b/src/ZString.Unity/Assets/Plugins/System.Buffers.dll.meta new file mode 100644 index 00000000..db649ce9 --- /dev/null +++ b/src/ZString.Unity/Assets/Plugins/System.Buffers.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 8e7af8fe9839770458b3b543b27f9b68 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Plugins/System.Memory.dll b/src/ZString.Unity/Assets/Plugins/System.Memory.dll new file mode 100644 index 0000000000000000000000000000000000000000..bdfc501e9647719549793297acb072d33067d4e5 GIT binary patch literal 148760 zcmdSC37i~PbuU~~dsp`?H9gZki!{}eEm7|3?pazRjTT#y7YXmSJhr<>vNhU_)mSsO zMq;rROAtsfHjn^GO!$&O0(pTDvJloJkc8(1!eV3+NJ9J!d=Qx{$l});n^?77rgO zb$2_LOVqbrrzkgdY091N|Iog$v}cvIxn$RbqWrK+QEU-=a6na*9Nu$yDoP)}0je1gA|3oUf{izUUI53W6+EIGgW11JKlGwN(zs+^dmh? zyOd|HPC7%|2){UzuXN(bD^4Ih^8?foX>PxOg%+GdUE(t@zgj}?iZ;V!}wPaf=pgXPpHZ$ z3PVO$TbDcuGSot^^)7lks_9$c2H+kRnb#Hd^_jp}%pHA5(63UNGJdrvr7WO43YGi{ z0c;RaYedxkNYrH_>fT7yI*vMyln0k2RWA}z(~&5&1JED8hN2Kp>;mhkL?&sYhyv>< z>K;NbnFW>*Q#TPnUd_zJe;i^SzjN2@) z7i}*gURAx6Q5T_tj?TZ6ltNt2tBacv>+~!B7Cf~Lw&#chFDagDRm}(e=EIMwz?TyE zG<9(+z&Bc10hAFB$NLQ}wUvX`#9;N=c#H!jROnwe8R{kE;OeaB|y z+r7u~Z^)>p4@2I45NxWa?`yms319Q?QBPAq^FfDM7!^=i5$YD%MQAV8iRrP>?husZvo+4Uu2%Xzs z)G|R=7D_~9N28Le%3#@pX9yZ0g2)~;=g-g!!c^z%L2LdDy@WI!09N{w^<@+nue9KY z#znMair|pOMRGc^2|Uo0_u^?15B%%#;$)J6Ze=S;OB+x2E0(_v&Az+%_m)n$2`1IkL#X4r8?u$zekH@u-sGNaGRU?= zGXXTk9yN1@GT{LupogVr_6S=??glmubnhm*P5+&$VkS-hm+(kgx#y5p?$)5R;_vQE z-YRz6MW-GES-cyPke<+$H$kgl?A(53d5|PQ^=|;qq$mQV5i1j{bo-v+8! zuI+3EHJwy5dE5K?#ARq*37+9(3X{0^E8Z&q2AI7d(XZG?__beAPf^qQFGjouZo-}g z53PZDKTki|e0suA{s!#_|LXQCK1@mAXe_5m&GdI87mJ3sIu&d*eHb<~ZDrDSa9MvB z8emH%kUiNh- zieL9u+u*C_>ZX4^D5eVPn1A;bR*8_}79FDhI_o zUMp%Ojlzxz7V{rWm}6!SI=X&CwmNI(*Q=RvO+AuVNjD7TkI*RS5=i^tL+zYYCY@0I z8;RYJr0&2;WUJk70yRzat8T*IK{msiD19>#QMY^oE@&rG(ni8Hs@=A0_}2i%f|JNh zUf+~>b^v1G8rkYkdppj;lJonUs^0efhmWNl^O);!CBc-0e>HH1xGJ#2q_eJ`s8-V^ z7`uyw!nJbqU5YX_?wXkiJyQ!3vi9G3Bn>quAuRN`$vR8s)5-qiv$y8G9ZA8b=kP~- zf**4%FISb(Gz{SAK8o&ZL@S84%`wD|MIygLkt2v4i9~*aB8Lz;6p2Km*wiRw9U->8 z`$=F6+XXKm+iyyzEYxL6cT<7krjBGQm84*rP0{d4s@Gcq|I*#2+uh&gUk5%ot~GK< zB7%tNP=xAFrF$fz9w6!wh%%g5M>NQYdQG=CL}VV#k#pT&7&mjzK`m<)^Qf0Rl-*ye zr2E`HbHjk!mpvR|XCGUlKF7)}103!pGcj&?pDDZMnu-*|O-8on1Xm+=!pPul#r zoZ^i=J_{qW?y1kBvLuPlITAXr_wlj%gZ>@L{ znUa}QFbr$LMq@XuxN9avI@@BeJoUAD4)gdTI;27=9;<>>|HZ(#2%`bC$6rHfr-@tS z@ElU011SP`pAL8+Fn^RXbYR^mv&-W2dU1MH z6i9OL(t3Gmy{H-g$s(t10|o2V_C*__*f+r3$4Se9h;xEGUBJBCfKs=>=?pk8ASJfB zke#xAGI~s1+CxlTfWy24FL*%C>4Dy>vve1wZA1utzThFq@F=%!7x^2d2W?9YN-b+b zMo&@m?h|)Q=HO*IoWPjIk2Ffxj1k6-Vu~0;cT!g$j`QyI|A#EUE1Quv`gD@f0dkK{3nE*X~phv(s zuunvOQnNOiSs(R9K`ew^oK`Wl>JsKs9PVpiY|%dNw5eNKy>Vj*bTfxs=l0JFG)%+q zBgSPKs7{&jK$Lj`u4!};+@bN8sIQ<-(CXhybTq2k%*QQJJ|+u+MPvHlEE-w27Uz+7 z=|B{96sgErxJ=SP+S$tQrGr$y>;t3yseM%iEK?v4@c-0mAiTGW-~2-aeGwQawSdu- ze*+$f2--#PWOalmQC=(_p*)?rFcam1Q@Fw$_R+s2aq?e+r++_w1U?^K`XFUn151B} z{#jn;qq?u_F5D;BlNp~#_%+IhK4#!M_=#ku?oGe3Jm^DmT|?qYhyv4QzuC4#bTHvj zC2+sJJa`306s`?cfuCKZD{+4MutY4os)FIC0{UF-Bq?TLM0*!KNmw2tmGmDVLXQ!+ zwk~y&q6)qCyXcAWt-nACnfwPuMKzYvGT2P~*7&#FD{8H={y>L$-bhn6p`(gr8X=*ezk4 z2*N2+w10xqrc~mENzf+rQB?v-SH=kjdXaDvP}ln}!*8L-%%TqqJN9yfroKk0uOJ+C z8$k7u$=Paae)O)Yj+q(%X0MU~D*u&~ndk=>O^vDw1t1z;)S#iSPJ>pCm;bl%@(VIg zr2J^!u;~1Rz$L$*v^|ow$sL7Rft#|@1m>{w^58NMF4>uPVW;%z5u)!_|bW>wn1c_7jSAX zG%wPPV%qWo){Tl}y@r(_e?)psE$#HnIa2#EwBl&tO85Y{n4qx1l$qJPf;li^@*kN;`+o{C2jN|ed4TApD3MVh~u8GJ~ikP2qMiG>WkDT zf|RBFC-tdOX2Z5H@fX)8&f1O_QlBWj&Wq=(PYt>{@ZRG-NH(_cgsZ;sp9 zsQ!T4LN3&}y&Y@_qNbxvHo{QTfcwUSx;#E_J~qnhD36kl1ld*|qkN3?H%LD&t-n#H zA>ybm*5BZIb3gI<_c!Y0#i|o(2cY&c{nApYx!6$|JyI?RE|x54N=4Pn9f6_G@BI zKOy?7+xu0~U)^Y#6VeNsR@GkxtlWMPN-XZN+OZxha*Yb#8RilhtZ1J#LJLvtTp}%0 zvk>d0(-O_qLW`!%f-kW5m`frfj0WcbqEz5M*w&TLw(K5qF*vWJH1k zw5C7{t(HCYhuDv@bQY+ve5L72kI);Gpzx8~4899k7vGCaH3j78D{>M&7CQzhEckI@U0`5JobKqjX>FETmDk4z@#M*Gm1 z9pg_0hTc_|UJD8_*`xVCPNZ&8Aw55VH-9x+iWV_mhk)jfQ3x|T9MXM{f;5hQ1Mt9x zlOAA5?-UcrPA>(TVTve^pF}NZ>!5G)M%@96eK9j(})*L zc!lFeG$idQbM?pYHd-`CX@b;*IOzTxQ5bfWVP+J-Br_Yj0F1wm{ruu+BFr!D! zvVA*0fVt9a=b>?NV+03!Igu%$7=M!{M|A1T{tDoiK`d404z0v&ld zvO%lpQ6jC<{9mK#L)yLv%@d0&y;y0f2lU0Cq>|=jrXtvlOux=$cIE$87Lk`lP;r#D z5<>r{2qEeFcR?p?csTDWi{Mp%2is|ALtN0Ecs8Z+TiS4qXVbckb$UH*1^2q<^;n#? zu1_ai+f9`FU2_O~CtM4^7R}ZM+puTjK-C+b#ug5&!2>uEh7%O#d?k}|SM$xeO)T)6 z*L#mlV0s>p$)7Zfn3Ik2ubQ{aDqNDqGs$VE--)n|W>{Z=dNxImipqabvJDy@ti-Ct zHxsK^U#Y>)Kv4?LxNLk`n~BxESow%?o7pMFHPckpn8YSc zOJ95fRI!XRe@a;GJ(0~OelY^MBYm-=xtOG${=}$t)xAS*kcJFxI9QY zL?g>_l*!9(>f$`0mwryrrYpPZ@M*0eyA_R$*hER-^>xSw9&KpOe>;){0D2sZQOtSX zT*sNwikjXL?Q~KPv#(Hs9-`*@!L}>8M*ZMbseafwN^~y$KU6Ki>B@8+E?zH@p}Af% zjA{rBf|uLsI9lovL({Gv=+QAM@-q-H1sw(V_+MaM*fCS~vq`I9TmH|3+6wmnQRAHc z1q3XA0&pANz0i_&O~5MEXRQ+O?&3g)$V zBCN3%-w4(Hgs!|A`7T4g&a0UA#yGLuiLG~H=sJN z#S={1wRq;zDJo8^#s3Q4zym|siMpU4iZw~jD<1X5e7PWBU(%1FX{^XIGTAb`OZWs9o#?;)fjCoRkq zh7;%xU}3(Q`AhF5P+IJuHo{6W=>gKB~G{mnXirU6-$Cem?8+jZ7C`myhw2`aRND zZw9Z?Kjw24q>ps2f}Yd^K1NV<-~totqlE#Bm*Z2a9a*gBHF>I}#;m0^d7?_=Us{u= z8f*O9ZcUzYiZyw9lWX#XAY6r)Dk4|tssAXJve6O1Qat_U@6|+^v$_DD6|GDsOn#Hn zA&B%OTT((l0`6VB`*&d4ap|`a#HoeZ`a2BS2Pj(yL&oyTdM9id@s<1_iLZ%e{)gyg z>30ajZwYHm5wOOvzeENouwb^&e30JHeh9y3K1{&mlWzlF`qPR7yl*Qs0RnqIW}?G1 zqXSmmpQ2(I_dob$ycc>KYVP;IXJ9Kqg2gk_s_BqYe@e@bN1IBOZ(H++HwAU)`$2Q8{{Jv0T~S_LD?75vtnqDtKB^8WxB z3hPB>Y1en)n8KkY3w@$gu^+0eTIj8Dd0PNQBM&gGu34yYJ|E-{Gq29Ff* zOtweSJo`t4Uf_8=4HY7TR6`s)0kMaM=%#Xi1lfRbAR@>}u!`XMNeZJxdWOd0f68|l zg(oSwgHbq0X;cqk6QBib6SARApqHgTW+0O73h3@8e)C>aO3af9p;}(rUQ^f-qB684 ze?srVmVAl|p*C4S85onIe;?`B!p%}?cAjQysknsP+N!RwwN+EG?Nk~HE+mwQHykB# zU~>j>IKb6oc{p9KU$Y&1-gWI@^V-*5+C1jLrPw^iGH{03Cv6_*C7UNo5NY}uj%K?Q zv3Ueiw|RtwY#u?jw|N91Z5{!wX!8g)**wMyo7aLBa@r1G-R5ySz=|sc)(^txn8mKV zxj;vxg4&$_X+$MCu)Jy>b2-`S{=#*##H=W>yI*75jg5x>CSId!TPSVT4yfN^`7;D1 zyiL($r@Sk)Y{Iu>D!RcJcN^!|1K_M_PGORqoNKfeD3AkP>9 z>R_-L6ROE2PW>(W&ck3%%y*LA6~2?(L*r(NyH0YM9b6~n5n0%E5~TF8q3b*-8dEf- zX!MA$5a%2)IkJLJT`k3od}Gpj7P}!O8sQspY_)aYHPN-AZzO=w5DMBtOUMjh-$+7O zH-=5Vk@B-|WDZn2pkfSqXinMY_~18mLCSx_Hxiz>Z#+cB!~UxZwUO|RtQXJ6hQJq6 z9`cQ(OZh!=Un^Sar3jz-Y*Qo+CPXB1aN?tyoK+v;**~!!f^HHV17@qPLZh&cx*9ZM zPQ%SO8qNX*Wy`E&52t!nj4)OKhL_8hGahtr@pH(DlWD4*$B`-=L994|j`cCjpG|(s zypMgarc{A%0{9FXQs}!KJxgc0f+P-Gr83=GqDrUQTs<>6ttL1Hv$MRVlB9jG?pg7JYy@gy;+nU5_$_uOD!rsu;3W(xC` ziOLGP0SP1>NkS`P(zywRBQ7Sz zgCZ^_?cWoE7SoC^v=P4di@2DOJ}%;7!u(PZCv_7SRVWwH4M=oYfta*k)uzBzZ3_GW zSXVa?<;!NihH$7GkfRW{BnZAq64cNQI0~s7nWwLLM?DZ)s20tbXU!ms#@HG2iaIhP zb%bfLg}%^x3dbqM+B6}nLTOOJy3)u-e|q{&LM<{+Z?vq`%=`YEHAVDwk7_vF&o*99 z3M-#7*kE)E`*ICh#t5Z(BLYp*49h`vgnr0s33Jmu;{Y}xWVjm+b|;znv<`jS`X)%L zh38M;siH+2CSRn#LZ&~+=~2NH>G#R>dpSKSTOu7tyBYsYoE}vGk$$yI-@@rpr4i}q z&2WA?L$BIVMHA^`GCjlTQRNirDVa{U;K0*S^-_t@k9-TQECM4>UyCULB_Y(LiAN8B zd&Hx|#PK#f!u+AABd53W2)pq)9fKX@Z{-nY4n!UCgfn9r1N1vs@SA9PmNW;nkS&v> z$ofFlJ|o2Bqm(8bkFo822pBRHiiK3RZs~?hY;7U4YXx^p;b29h6V*6rPA&;A7QfK( z^dOxO4hk#DI2A7(lvFrDd!H;1slq`CCX3kVp9^UlA7~Ip4yt?RAgi5B&xfoQ&cu#6 zsE~~^E#{!?n1c$1Mnc9M6nH~E>OY`&m=i?bN>3Uop?Tds!k?sd!PFl|;~+|Qv0h0{ z8Si4@Is{feGvu;RzO+7b6M$V^s9#z~_j4!fp8@y2brp)X@EpJsR|jlO;fY>oR1X>M zhb+g&)_)>72HdytR1+~-W4NzLxWANe7Z@%ka}4(<67CZc?!ych(@%!`bqV)w3HS31 z7t>RQdy9m7Ov3#b!^QNK;U1Q7$0b~i;bMBraPtzbBH?bs6Bdl*s~g<}YD{zl-wk<@ zA!zW|(41JWXSHeO^9Rrd#OGhbllb?`c(&v7TO{0L67I(su9eRZOSt0_uEub!e4dwZ z6$y76p0F}pk6;6C%V$H%fmDCWO-ehEU?q_C>yu<4 zRoDU9Rw8=(u{zb`nFz^b3ZOL^wgnP|tReACR5Kq6zR+o$T#cs1Y(XMs3lg!;YNDMj zI12>~eXwx8aUZ-JO;h*5Y|)#{fFV-RrNoGG1wR~)yHqU1hZBtu!8y>9~`ut=Gn+rl=#QNBcxLutF*2 z@tGvvLO%>|#NEkweZB>CqnduTu7nLgjM>L}H~1PFH%iAQg`%SuK8_;Dm2i1X*z@+s zBM}VfAJnmR2ZMIBGn|l}VbK(lu&1v+RUcqef7tGxx&6Q0F_T{&)T4e`I^<@@OqROg zn9m~A;+SPJsiYZK$rkTi?$Wc722e2}gZ*!pD90(7;CU z%}6-vgA*M0!DGFb9tnYaG8tkS+`lyMT<>YOsmE7|JClJB z+J$lNSL%VLac^hOJo75#LAiAmju?a=*-fvC;G+&j9XY0?1`|;Ok(35Pwrbr%)L`CN;qH{Bnd zF$hXnW8Mi2Y-@21Tm9Yt3uN8$S7-*&!{^Qhw&79d!{p!TPev#4G%=6Lc>KQvkeqQ_ zUUe8tZBJi&9+)fke#gr;6jyx=Fpf;p!wm~%qZu=FMH z?v^-rmxr*H+luAO*>KN-N^{f7M&c*kKZvs|HM*7w_W;`dGr*X%iYdO0$^TynO?}fI zo3niEHo$xe@{!G^*`rOAUl;9>LRd4VG$ZKJcrGKHzZR_H))AA~g*o9LMeA(5DeA(| zIuWj7UbCrnewKJD#F(llr;0@zO@A^tEilU#*m%s2us;R%M;I64Zm@rQ*jTNYpA6Q@ zyfWKv|5+4|yQ{Ep5Y7^dib`6Z(u`_-jV8`#W+@#RigMeggFtp>{M*dwF~Mo#Ggi~Z z{dj7&Ry}}g?`+f1HOyYmd7BR(6?^Fh05gcTSnUJ}b?jiDLfg%8r|HB$n)w^lTo?Z4 zmc9yt>Gmu>@1QHMKzq#~59oBzhSwuu%YDsl7|u?KN(p8T?S1;%kE1{_D0v&+M5_OF z6!7%5uj2@MXQ8KQjT=b9Z=|1_@S`_J_?WzPinBH&V5yZe9ilNe{9Z5CvQt>0a9C%449!i=*+=OX zvH;zhp}m-~Q-c|Oq}r$2*K1p0!W4U`f;aAz4iQ2Gc&2Dr27Z-bMktWd zN5(%H&{d8i_s@ykDLpgscfydKwG$g2PT18UtnE{|+3J0@{YU%Mena!WfpD8PTqyIL3j(f&`kms#yM@%?FppylP6+iJ0fQMk3_i zx{!OnVkb8C*diX>yGd|Qg!3{!izOrxGgN;YhDE2fQT*MYqDeFU9DDFfiJ2&hEj_UPA4BdC@>#p~p4D5c9>%+Xf zOl!oeP^tE7#FRoSQavQU&1=Mzh*c>V*w!^-U3mcA;SrQ2`yn$gLVfiyG*NFCJn|l7 zlFQrOw7mUyP=_rvQl?bdduzVoam%^F^3e zTqJ-MI9A*zdF2E+kJF(Ei|Md$#dZ@G;ERJe#Yv9iDDHz|#}kGkP6cVP>8r3+WIoA% z8H!C`nX&0B@*6Z=w2kC0IrARy6kQXNQz7fUUFLG8A#b=8txawhD| z>X?aUf165r31`CYt&W*k72+(XH9Tvqk~FO9*tVM?_jnoEPUdl?wnIOnx%8(IwQ}42 zc59|zDW|DdPwJZ{hv@1DnHsYh^Av^jnf{aW~fiK<=2QF*~X0X+nD$_YnCZ4Bg8kvbt z59WC^g&I-%>O^}oxGHSZo6SHYe)!Fii*6z*w zC@Sv0--ak4T1g9zw<6l#is&YRXeG_KycLn#ifEaXr3YHyk&#>eyj5H1dm>F$`wf9; zCE=oNckxEqaknYBX z^ed#hJuwg1EbSklTyeg=qZQE`1fq_7D;|sEDBcsNq_8Wv5p)O!b;k0dCM?-FmZH@I zNB5z@e2~qo2Y|NF*8s!0G1^JTT_icJf~Bf5_CnR+|sg1B~CG|)mjb?8(xGOMOV11;dR z;;Dv{L4x)bX4^KC#7Ab^&WVm0%_(rl>>|xTTf3h}GrX0-FSQv8M=!k%3Rl+W}4>yR@G}3#RM>jw12U#hm(LZU zC5qZ0C`@DTV9`JyCFshelbLjCW(^50_68DTbopfI=35Yv;yS_yBQbn!O2=YVnBB$E zr-;jL;24g=gn=eJBT<+z&;&CYg$V;qFsq_4VW0_SbrdEHG+?N%V{?^s(oNy;XUa_( zbold&P*ZyS;r?wOC7t@e&NdLcz)(>fGv4(d$1 zK}O2>9Hi#|fDmG37B{Z=|Bi=a4le9JmQ*tq$C}mx7UNOtJ|!4K(gxim#jU4{B!+^P zPycn;XTJ|+UEQ`UKJ(mC7R53aYatcnqXpRw^U$3DRRn2U3zby8&@XVCY6^J9zW(eF zsUCp`+e}8qzY9OhgPX{EEU%&mdqaG~RE9A9<@j5{)8c0-4qFgZzaCepqq&>WP%6+c z5II#w18HiTrNUV#6GxU(5Xs$E0kqCGu1fL`D+0Ye99-M$- zn+D$n5BN7Z^ENO>#ciroxWAWanui3`ooO^mI?QO4?2bgEWd9=?CHolBDA|vQM#=6$ zBg%4Qeb*)NC0aDXmOWS}mbD7w3b(wF5)O zTL8#`3L#%s=~fSw-KJ1C5rgY$pFMK`T_3t<7ZYW4i_a+v3&Vpm&7AnT(BBP;hy{(~ z7v`2Q>cG`<96BZXK@TT z{>XmZg@^A~bL#vVipIS~ob2@-zK}oIfW?;>H7s>YpxW6QVAmDh_5L1Ew1g!jXWco9 z%R3p^M{(!hHIT^xd=3u~>S7l_oM*K4&nQ|Ug~edLKeM1}_-Y^7EeNa9)2C>VMm(||M@C2$8 z=m!PhY6cvR0j?X;>%cm-tCRnC0? zI{tJtuuhGnJQ59HQ+*@Pm!bhpi==Fg23{Qvd^{TX=V)NF9zk%V5xDv(gN)bBsO~wY zT+F%jq7|-1o6&cuywSt+j>(^+f*dc0d~8&8@~_2N`~+T#3ETsN5=Jw5`fi7VsPh!e=1ZK@PZBiBGL+Y$tX(Lp zSD_EK`qC2U7J0vtPWPKAyFnM|uM>6>?sxQE^s~-6 zPY>-O`sF(b2B2k_%sr6{O8Z@)vDfYi!Up%Gvx?-tv-*oa@vx z_>hdacL(O5zFSLt0zp2e8|96JsX|h-Z`aLP!@>>5+Q980p1WQqbHHRNPI@=Kpa86u^KJ z5xD(A+yt)D-GPC|9aeuoQS%QgWTx^d_X2%Mxh1RoPBryYZUEoZ;vnAzDn2Gj*CLI9 zU^9jGT%!?Os~8tn2gTPb;cbG4sM5Sg z6dKKaDOr9I>dJ*f-Nn6X2Z{YM^)xnz5~V~PeZ-LWbE^Ceyb+d3pUPz%RA>thN)2%k zKplssputz*m5+`rT`)&#)(~M(LL8Jm_b>ZL094!ip*k&vz zyNU5((E^>>qze0itHZHx%qdVurh&FQF<9zV6E(~C8+aA^+%5(qW-|Dn{rd7C6@o3M zY$Hg{;a5QG707^VT)0&xF{4D4lQkF;H6WRwqEHigGd>7CDhMUJxdXVMYQV*G5|v$& z%0O10uW!Zz9-(5Q`g_S`umWH@)&YP2gn2j$T&TCC>x++*X45rq0f77(%H+92jrJnb z-H5K5Su7xlYCy<2k{KB4*<- ze4V0TX{n6IIZlH3Y~VQ6pT;v&LwEE(^)v>N4)aMpjq_;Y6)Aw8A!zhJ34)%KoIg$< zfzZ)zXDC{QcNZZ}6m|`LP6gh>)e1X}!d044>d_WA1K8l-iGsGc1tH?!Ry_4hqed*E zN8gmtj4}>c>Ekx~4|LsUK)1Jln7Wm*qWzE5qqzJhHC*|f5|{pH86PWw(F__c!Sp{? zkK-K6TA?R)$(x0OHjr52*_>a;Y09SjB$MdIDwyf&md+7v$dP#edWH#br_Le{pS(Nj{`=)F54gE%wYkV3HwdFuxtPOg69O3+SM zwy~_F?S7l32UjX#La?SyUS?}YE2(}!+H@M0?sn60A}XQ#7#}&wnRgQw^cW5Qa!y^m z3eiZ{kh_YDnh+w1B!bcjypZLF99-V{kX-6{|IU+{)Crdi`AlpdYPp z`N0hKi`TSqYfz*%kw=NKthycMWSd4GGZ6mBP+;lk4jbZU$V%7`qLl0i5t@v%wyx4( zEj62{Rh+e`NqN1Ac~?52ME9!^TTHvUpl$mluu4)r^D}r)Gl?yW1T$;eMBpZxn#eLWq{tRZ!!0FIXJ(F? zAfB>8NaOr>7)>_FP+(ycD2WS`EEv`GpJ7zFnNcLwVY|D!SzXY#{SG)KC1K`Q@h&*T z5=&eoE?I(;%r)X7@H^llL+#WEt}=r1UD#bq3}TzzO8v_20j!}gPfSpr&7ngz$k4Nu})cHt_y zGgce#MhD|TWLd&CS~$X=#NfGMau+cT2d_(>^)YmPyTrr+rd)0yV0`{q_)(hqz&);{ z$_9NH##C|NoT%4ot{0CDbUs^!SwpN>>L~RlWO9sxrCI06=yJcrP#{)x=bWoC_Z@sq zn-hx(^uNg5(`X0t4i2mXTLEe#d?18cEN&RA;!#uRI1U-urERXk){$fvh5=5)G+Z;o z^1b3dbtx1ntE6$12jg!uAshN4d* zv&{SuPvCPSeh8P9CaD`s)j~H`rhvUxDd`nSb`Px)XvPf9H;Vff){e8gHXpAl9wsTC`WLw z8&gqd2>Qc@g5IpMm*t5~rp}Ur*;tkvogdwHqI9(_WCh2_ME&S!5R1i5@`Wj5l7{?X>9s%IkptL?>yns1EWgqCk$wn@KMm2=rF@gJX!>rLB zBSwp*lY*{lGq(+(XwH$g<$ z&<^EMy$5vZb~&XP)3#=A(hY0lUO`=?Tn*F#vO$?aD>N#A+SP-BY0)%66UDG@jhmd6#V}Y+Mu*P z)CJi`f|N5Gty%@z!G6D1;jbUnglt0&mH9?l)UFQh=oE&!&@1QV25!gh7|ii$LZEI( z*NtV9#ADWo$N@JKfMpb?OS@*!JRr}R2;|ukO}`DopusOR&^ek6u=oxjIW%g7%&acm zfya5uCh=-SKmWBgOf(NxOo$?fOGz=yh-%?R)JUoIN>CyC4b|Bg6=d9R&te@!tLj>H zS)+xMtNBLurCGqAyAwb7Xh&uqpZCgvlymd2Uz&0ruLp>?yy`*Sjfdc^&)fy*4E0g& z#!GiVw@O#=hRfM-jVl6G1d9LLe4K1OPMS+VTuhwlHv}Yf-!*@k(&^wiVmZrK)qZPv za0g=habffvu(;Nly?D@AIeb##6y8Tqd<^akzaZkCFoItYac>yGFNpXFnnK6(b@bdN zp1J2xNA@(h7MCH4jz}RMW%9qJGepVJy+f0R45Q4a%xHb!03APIc!YwW&D$fyPhV{C^1{cL^+!5L!^e6*qHUf3)4IF7^Z-_$nTj;86hAo0h${HLfkG;vE**XuP3Iu8SmJ|{v6^qmoU(tOVs zDF~b$Q z^{D=*Q4qH795bzTxRaL-_1br+{+}YYJ0aR_Pr^GqwW^WsO(0^g=iF2I!X0?K=K|Q} zGy^zw00#iE%*bYDEb&POUVq`bPSHvXy^+w+2bCTbQt^6v7-t^Cg9MLa^Z%fprf7d2 zY$(7Tao_;+gy66ocZ!~ie*tvr0OwUR&oahPreHj<8UdcFi!gsY%>F$*mkvsa7cczT z&O;QnzHX;zHtR5zC1$gLhxB|}RTRu`LeJra0!((ofd)y)$N)gGJ%v=5Cj7fIe3`mT z*!(BxE}wlIv}WFTH$*XQ_TVcgnV@SVZDrDS!uG#~DooiJ$m08V!Ig>Oy(4pY*+3_7 zx1$6c2>&}kq`Tej%=Y&J83w!}q1*p95?pLuCdZ1sC=glKo_f+{WIJFjXj-D2>d`kJ z#rwM_YnO=B zE_j)n1nOI3s6%uio;M0SL)D3c4J2OQp$mHu#KvD{W?~Fs7dyUTXxCuWKeZ1M$W>c5WqAS&o`rdViwxt~DE8?4@$DL!hA)81x1svmFc!b@*%`TvG<0Zq4nj&Y z^>Q=`=EKSEk?25OGbz&?Iy5r31LjLHH)AA$G%s+d$lA_~EmN`BVM3NHfuk4@X)+ zwKIk)%pT_3UeCu(oPdiI^){%5>4JnHi}AozHV#LgRI{m%W6ur?+Y9FMeeCLP2P+T6 zJA7ARNW7%fVe!(9-ML&72bbLN3)VHoOG=X((rtn(4rYQ6Chb)RQ)Xh`vFv$xj(OZp z|FDWp3!qFEp%Im`6z#$uVY4(PhXy>_$;LztjGe>A@%f$j z4pqo(QhRF3r$A{9Jk*#o)N3HsGPnN*;x%n}@9-Qh&>yL$G^r-M{2ZCZs} zFj27HHN}njs4UkKDj>B>XJ)~erh>~OP+YBcP%v-Zfggcn=68a`Y~&ZQW{$dNuxbvv zsa^;0#KMlN?#AwyP*TSZ&WEx(?`ROfLqcAYcuyVjw(l3g6gE;fLJ;P9N*Y@cfFwaX zYFynLIyfJecO%LhZ&Ti-7t_F;1FkE9nd&i#cl<{^#tsrLr$O>agGPJ<9AqKil?we* z?oa0wsK?{vMb|y`X-G9)$myIT-|FpnoCJK`Q)qk{O=6!fojroKKlgL=PW?7?rWLH~ zz=u<(2-7X_@zfD2s@MgMiidqM^d0bhhM>0>I})~`5N~1+b=yrTOjF-rSdI3fC_3TG zeFty*N3dI^cYh`KI&{o1E3Kq+1o{jDF~-^VGjc0b?k6x z19To|9s^FSY`ha-oAD2u{#)e9gEg=NS8vbQTEsRcA6quTg|aZc z8KvFxCIsnClt&2v>jtg}-RQ&e9w5q(%S{~4Pe&(-c_tzVLp%}ZT{Nb5&3ufmeJ%VlseG`ZRK{B=7i=-9eAK;^#8q`+$@Icys$8S6ta>O~68QvL zH$$(=_0o>UIed&*9PI0W$YLdj9r(Dx8_*1MwpaD~nW4;<8X)zI|3h%97ru}TfH%Ge zwR|Zh49kSkNCFn29etJm@0`QKIwfVvQI=zr;w5Dse8!uTwonpAPe|$sllme_i=5sX zJtzbm!QQT6K~4d$vJF^VFbMdqicjk zBXKVU8qv@ZYJ3gbU08j(JgEqE_0c?`2*4=Cv#vgxHz4@c<;ji;Cz1MSUN%gU)dIpU zPu6QUy-SYXOz*1%J+pgsZ#DIh$%b^~@2~y0@b}mMf6U*PMEH9w!rv1O{u&Cp&&mn* zox&?6;6gtSrRvk9zj93Py6Sc4NhrUG|26!_^e^UDkBG>(BXB4FW5!>Zc@{s&MtyHF z1(~F&Z24hg+Vz^myoZVvIP?HaJkY@~F@-L~W_Qu<@5-DR2FI~qPxox z&e>x46EYNZ4W*5KOwpXeEHws{JZoU~>l)tu6gj|tGel#qgk}})bi`&QG3|i0NFcBz zBQE&Kh$khxO!GV^!8?^p#h`=gLqjvHlAoe_@RVRSTQLeaC|JQk!3u`7m2kvwj|)?g zp#iJNQ0VRLN?<-$x~SqF>;uyM9l*Go7tjY{$rF1p9}u8((#YbPd&E39Mh|JY*2x3W zRIh{_R`B8oR&2H@uEvlkf&;@MmnN0d_*~mJf?PDowIzCD5p9+-rhYq`-lJn0E;EIZ zLW3kP*b~I*E&}LC+K2&7KtLOLFcpP~=m~V;n`7_cSlt%(L04dAl$Tw+4b04>X5!Rl zq$yTv22{Y+i3MUL=N0#unTh$P$ca6{?fvKkh~~lcSMdrnQRV5GAlm{Pa?CZSz8(z6 zlU-vEeU>j_PQBmAT!r2uMuV~PsoiX>f1WkWBmPc^LpqU3JMBtwKs4<%OH6&8HveE> zP;h;N$fTPrdO>sT(B3vx);6a8hT1z?w3}qoTuiai#w=s%w;H^^6THV#N?ZA-i*T{0 z!CuyJd+-3|*16t=6vGzan(mWKDhYs!-l zkXNi^v$3!vZT2RB(*G>}CqkRO76JON;y*+&YOwnw23w99dbQ;Yt!^y_kUNYsO#f%_ zA`g(ChL=x@&v>V7*>aQ8tf7%v&P5LdOW0=sjCp#w4rfn&O^6crap|_kS8|=aYk3Tp zvb}4k@pE-)6mO-T;0oKjrR3S(ZKeKTb?$Pk)H=bc-1<{z@Epjk_piV+<>j2fl7yQV z;sojDg;{g#kYipb3`RO+)EPSq%Ft;>B6%q&7@U-P=6mG)Wshoiw{_}Y5Y{reTn^jo z|Aji9r@l`yL(!OjrkIgv%s)}gszwatWhlf7!-9TKLY5z(V>l+?!`>ghYi6DLx0Ztc zwW(krg~@4j+Pg+0I7eD=8rG?QZ^8M4{~S)R((iiV#XTnV4cz^#&a4`kPLVQ^n$5hjNUlTj;RZzhL@4&-=)^LS5u>y zk$McxSkz-SsUxsn{ zbgu~=n4=N;%=xwyhJFW2WrWZ`(@YsUZ|Q#TalqE9!Ry@Hu`9<8g_Yj9)`<_kxNI zoPlYevKc=Lq`uyZ@f;*yml@y6Rq?x!3vMG3pD=3iO(0sAjQmBx^QCs#y{U zAKx9J`sa#+>` zdK{g}hfkbE?Xq@*e5@DGnjBAW|r#%#sNs!bv}pHT03i`i##ahBIM^C~3HBC1YahKQpdou%=l_83lZc z8h6pl$)ZVYY#_nzfvYy)HdQ&qhu^|t6}wH<%1rhk!4j?WeTXFXA>%{z+*m?FNryB# zYsG&n={w7@iVIzYJz!mdT1yq5j%YM$$tv7NaXHs(rAQT!8A!mu-oMK`M(+5!CgBR5q$4 zqz+6Q+1?jOXT!p=jte!-w5Vycd{$Ceo@kt;$xwb0H1XP`kWma_hxaBUk~)OzIV#;Y zKAKJ&11jB+RUS6A$ZDdatU@v~Kq46QZxB^r^KiQuqR8i?JI{e^Me>lOxz4j1=)({n z>x?RyX-QcEn+VRqVFg_#&F#}1pfz4s8*5fCTF3te+xr9KxMe60rZ8Z~ZUZXKR*zy~ zQFe>f5v*vpgU4u%eR#I#J=Fi^p@jpl9x`QzZ>z_vkG2hzX z>;DJ1(CzjfOJSk{C6#TvFt(by_b`BEgWh`WLTa^*g|6oS%3r20U=IQ;bR~&!h)uU+|6-CeETcAIq&~L!Yb{klW!U0YnevFTZ)AqcP?G~VDE9nks({5-2+Aa*7C}Rg{ zR;KKslrV6-yscLmk|}pmN*Fj=IMtQrU zh2K|xuuU4KFEPvOBDmFd=7E;ikWvJPR;bA(XWKQ@MRj;plz_F3fop` zf$=;A(bx2H{n+2o0@M`)!l7eqhTcY)QdlgbtlW)AWJ^%s@|Xro@v0DMu!@4T#K~m@ z-4u)#iNzh=$2UC9JOtq7JPpD=Y#(TTMAi`}nr28)wguN2Si)RGRkNsSsbB-Hq!JVp z_4QXAhQbj|!b+X;jr_tB&tXZJVxjZahH@38>>Sx&xhr&J9G?!FMZKIp+!74 zLfe>PRR_y!?bqb*baTaUyb}F@pSkPO6jl_a_C~58ajP><8-af$hHiE9($Hlmv zis_?bT$&bEuqb(va@+>ue!%xPf@!y(%Sm@Cr=QA6V<>8y7NiQux=&ngW+wB29a7u*EIs5*K&P5m_?d1YUl#ZRYbpQ z&d~~*dBnj6O&A_p|2CIigWo0W#Bt6O>Swyw*Gox0qh|4a5x%33ZlV~iDc!pOlb%S> z_rsJ|gD%)PJ~Y*1!qEF$sdi3}6Ow86SUq-6qQ?;$97!SF9R;54!1H4Anw9fu9dL4mr_D}Fgs`P=v9JY)obN0yI zij5-^RXg`4g!fh~5cHOcUddLw6SXzUCywSn1+wSTy1@-NhXS|FReB7X(SQimWJ5xF zUA@Pw;n{=T*FDzKqr@KJP=O#lkyQR%R}{<~)P2n8IOg4%qi{96MJ8qwVM`)55w;{^ z(_u>@CcTp>X-4n1HzO!0G>pYkbDoCz69yz=?4tIgIU7t1+YXQ&8pL+EBj%B;M#MZu ztwsxSX)(y6hW2l^4dqeWN5&#z`=Z981-&#Bal6+H1$+^kH-KQo<_)?7Y>NhAi<&bc z39K1xws*~7Kp3%g83ZG?F6(9(f3_X|4B@8*C*%qHCZ%@lk=+yWMniy&bVh~|jC4ju z5RAy;D1s4TT!mmn8doD2$`de;xkDiJa(5WNW9|rkhul&8_PeX_n{rp<*L26)Rb+@a zEzY^ayfqOnZ-h4-;$>9$!wPVaLtKp-S6tjZOZ$BJRL|%n35WFDbbT*Y2)((|M*Ie) z3H%mIc^uPYH{jyF5%vSkO`vR3z<@K;}SgokrxYgq+aIo$t>jq9cKpkEwQ&b@-Pt;qL zvP4q@*w&7IS|4_}C&uuDvr1Ur&J|7^xMO-Xy&OHht5l_zg~gjoJ7iMn#^7dpJ$e7^ z^Z+NGyrbmFn9}-Sf?kiDoGqp4t&wx5zpNDbido5%RO-NhUr`B<~%w;}7oK`a1X~dVk5uom(H5 z?*Q2P7QD~U4<#Nvva7V0UKS4AP`ZU)fUI;+@N#;6<$;^g7L*(e9ft#UXBB?YU z+)l4ATfC)o6}_A|bgM{w@W>sdwZVpLD%duZ3TB2eh#N@-6QlUJ@v2ndug3X|u~Yy( zNCl&wlL|6kG8MR9D%IQ`F|!U)au!&9OWJ&oj3q-x(&}w5`7Z)+? z!`l&B4zke^lRd%~)+7ttgn5`S<8To9gV3nAVqU?%v%NOSUN>Pz!_2v>*zATLARRIP zkXcMNhE^CMGImlg5X!-BLsrLFRy~r{+)#u`)i zUylw~oL@$`$Iwtd0#U|UX4fbbjBw)wZI~Fve|j3>#t9Vx6aVQM*susGSO%Jv!p?<& zuXPkV)w*;OQy2%y2hchBH9SpV7c;M+t(i0~4&!Mw)p&M3YccS>hsAj(OF6|coG1R}1($)e}xl86!5jyt>{XB=C zPdtZuV8u4bKS|>RksV_S^)kw%DBpP`e0fg3{43?am`C3GXDBqU^q=D+RwO#`v0Ia+ z;z}MI)GUtFdD$09>A=tE#zN8&v)Gb}m`L-EIHApd(nXI=y{zt*yz9$H>u$+gDDSH~ zChxxTt##Mr9WCQDMd%0?%F~Tr^3k&2u>B{>=qiQY{gve&Tph=^m-ZNAkuE}FJ4RfQ zX~tstXM@$2>OVz==VwZn_N;7Z*HC~+VP>5(DP>qy=sN?hcR63v-Gvi2l11h?T2HV@w3k-6 zyx!`1sVR{}fT+a=55BXISXgX=vBz3-*`$k@w=cFPp)V6+q}gC%QwzqC)@&5_|Tjv`!-SbEXsZrmreRYWxqO7_CjZ#?}_kyS2NGi zE^(e;PCUOkEcOK@9j;W57r+ zJuBhgDB!EzQTPp~8)XZ)LXFZrCoyMNFpbfTF(r@xH{d)`y&g??p4+e~0Wd>&lzq17osIpNPJ=tiyIiD&DT0 zus10JQE#U~M7OpR&TK}2qwVzfqFv*%zVl1*b`^a8LqxXc=FVSf2me!@;a}bk9#`yi z!oRy6{8VT7Y&&>t(Cvi(8|~!mLPt5pl2*alqSu{_fktg7O}xN+LVd)&)Q@IEJ5=RjNTrnn-g&O zXe(~%l4loSVzJ8yqwv}kuhG^fyD=)CrO#s2=I+EisZJLgxF)TJ$P*P3+tf#AzJ>-M zj22^*>}8BNbix?1BFh+|!A%%#!iW~2X`x z%D55@TvldTrHw^nwTWIgS+HGab!}M%6X{cLDOX>E#-+a$=7bsn%zmc!7aAOrb##a# zd8kCzar;B~dPvB=MzQQ~$x6p;(6>SQ#cj}&T)|Kj+u5LBjzQR7sdR^Qp^qX3W+rY{ zV&>T^l)g?mu9D95P(-f1N2EwsCO;lror(M5sk(Z=rLQB+sJl;0@r2}(jr+Pp-Oh`W z5AAQ}3puTe^W`(KTDRlNdtwk&%c|tdo7(YZ=c}6F3+Rd<(@shMeG%5MQ>t_4BQF?t znw=N%XH_$QaN6P$`17S$ZQAkYcVZA!)x(lMKZleSx!FmR!_lUd{JBZ;=b;3f#_0nQ zJ}oqv#>roQ!B`bDqQs{wz$cK{=+D}SxVRjVO={Gt9iKiCgCIUFNItzADa5B*OgDD^ zY*PlwsJkSiPA3{><|SZOZO*Qt>srHd^BR~B`U^F$R@wNj;F?Sv|ArNGFW0C_RQDRT zOE?}j)u57m&k;Q7ug$pc`p6jM%H}Z$W>Mo~kWm_gU>BAGI>Tdge3Tx6 ze_v<#o$cTYo#EYf@IUO>#yh{-PKKyg)1kh<*$)2go#D^7fiEn!N50|iNJ}wi3fB>& zoqOVmCx)jd#j}j*>FJ5f8~S z4{mVgLhkBFk8j0#G1eo(Nnk+ZyaAwX9A45a3_-9vwl;@to8p9%$T#)5nRkE&x^npc zWA97At0=OztExN6z1jDDyCH;-KuB`42O%r_DvO{f1agI7NFWIc0veXV4VNh5uAn%| zxGRpRIH00~ijEHGxG)+NMp0atLBy5+J*Vp~5m4uwdH(17pXU$sTlLmCwVkT2uCCi% zJ%G0yuF|&)E%eT}l^I^h_QuEV5<%{FnA0K)UrCFM^5@-(y|+&-{6q2sp~$sN2jc&M^}6!=*pk2E5FF*IX{bMdHvQHcRGwP_e^ZbPt)?? z+OQ+4=skEln7_l{*eB;w>IJK#Yzftyj!J<9;kd2!JWJf@1(8olrnX!Gw1 z!go1PC%g=zm!kvlcp@*<#OK%0$kyLGvia%<(pD3Oon}k+#F==v&ONTVN1dI#iV}x~ z9!fzk^!zLZEb;iJpqF;y3tx-JxLAQ`+8#fPhH=q~mKKHqT9;dw;%8&u)84UI!MXIS_JNMaK8e4@J~Z<=m3`>f`Cqq>PYT*TiG{Bv!ak?{qJ20Tf6h^x2t_}+ ziMIHdh$m`fqo|YH2Qw~Qy=Pg@;+p@`Vg+IUB2g-_f-4^19_DK zTHL2uTKF&aBW)v`+EloflbvVy9sZa4kv5V~3ff9(;f1fJg~LvG=Hz5&nzj=~bT1)< z`AnbO<@wne_n42h5EW&k^?(hSw_gi;;g#^y^$4L~t~Pkm+xAjQ@@q%UJwikKo^Vhjhyeq{)OJfL+3~CWke_5Ua($6k3HRpU51?|OsrjC zc86gKk3#DeMr2QK8y5FWq#KWl;f*3}SCK|hs4!dqtlS7=DHXi;h`6Z}Bf>D( z3yTN~7=WiZBRo%v=j{!M2%DPbv`xj{?bVo-(!-n)VG-e;Vn$-FOYh)wX>AeV*cD#4 zi!&0R+rsYgx_!9NJwohhA55pG(O42{#+^>}@Qa(SBY4tr@8yG402Xm# zegQtAO({+d3LY7R@59l$h&y$>EsM4Get8Bz=QcMTcI=!R5!5neK#0MFjh%cCIIV_KoXF4-a`#z{XbIDR>?(>9qZn``rXQ zZ0W1(NebK9{kM|BMtJ|Nqyql^r1DNtK^u}fm-WZP*J@KmO**ch3(VQwkEX8<_xnBf*(4~&{coHhk%-%*B&|{j^Ua>j;OTw`& zP>}x;+_huxGW13%i<9jACXiRiyqQ*z^$>ItQe>`*+{!6fmX1et}Mh&*<6QA0_5JON8`t!ps24Q~v z@JP|nyfhGOWPm4!X3;Cjv-9Hou#o{T95+U_4PBGuC^7axb1s;8C>C&@q>3qo^ zKegT;S!d!%#1W3ejsqi)D8Z52k8YZRbNk~xGB{Z_>w)p$++>^ex=L_vq|JJRB{z%!x{Neb3z)(*r{#>NFX9n9G$dUd!L-Bz(Ulkhy zrUvB>_IJ20optu!A=vo;BnkNZTtWK2Dt1aSC=?%FqIVgWQ}OluB0!vmv*~B&C!Xj2 zE$3&vyq-6#fjKCwR9fcqe>0fhuRR_3f_dsWVl&z>Vbe)LAp; z;G<31^XWW;yMWv*l{!nM&YbcF&S6tzz)B|iBt<GO3q9*j}vN1OUH*4(i=6KLUVA*&)4IDA?&Gw8E|gkMOUL&^uy*s=OIhlG2X2c z!#Y?P_t9zonGSwkLpu1S&qrt8&vb5L9jr9^=(PS!2iFFqgH;G09WsS)c?{OU9jK2E znaR>oJQ&daXL!yIw-|0EyI~CDs!c%EP`4g>m|FYjjmW0z@kauFriUqwkKU+ksv>`w z;AeU`m3;JuXHzv#mM=QBkKRabtdr%7A;?E>6!!|9@5$S-|8HnV()qP^B%NPtN7DJV zb|jr&Ye&-g)po>m;WxD->HU^=B)#9#j->Zn+L82rOFLTmQgzXeGp%zEQ!YC9!XfB2MFMZBd~8JmZ>fB2 zMFMZBd~8L6liG>|-ctG4iUi(L`PhmC-ctG4iUi(L`PhmC-cqrxurSe`IAvs7bYuGQ z09;&h&OyM)7Aq8MH(_ErT^eTO;Jp-9Olyq&$;cUmPYL3!`#=@5tP75{2BG-6!`Ff( z6iPpBsHLQqji(s{2iTQAYscXej3X?8V#Vz1C=E(;Ej&o`dg8c-(U?isGAm6AwbCTD zY|Q1YG&$T#ljAR;fb4aY2BmoeJopgijl?-kLnOmRGh%OK3dO4>Y6)p!FWnlv1k;Mg zg9CXkoCZC_iHN&03gLnN*)UP=(x;KJf9%y1lzkUW z&#l9U#Mi@<{d**dZziiH6wFp!K&4u?0aV3t9K0i@BePPl!q01*iWNyGREY?Mn_}r( zkQ6s3vAq;YUs!0-HI%5kJs=S1(7KFiKRM&o5~=`K#Tlext)gO!v)J}K5sp5vu`fe%aahfz`kLbh4o}?@rZi z0+S?@0y?|D86sD(-d$S-9Z~ztW!(rHucwHg!hO+_oTlP122X8WI;EczY@VxcUvSc zjcUu**nRwx*WZ?W7ToTbzD=2%9uP z48)=W-L&=^I%zoOy4R&O`+OXuaiE zOV$ZyX>EM3G=I?;Lprx4J%lu0jw5XEH7Czs6vh$W7qh?8UtAMIIey6c;|eKO?3tO}O(R^IO4t=kco$0UF9v33mivo0;>kai@k~Y1y%AJ~ z%oqyKX3a}EmmlS0f&StJPCvcRIVkgLuEmzvhjIf&AJq)~1VuVOW>Jm4$R?X~W)ik> z$>)Vo`o{+lz7Rv$&Q@K=Dc=!6A=`59MXgsy5bogI+c@{P93o)e!g+Ek08b)?rmqa?Zn}nkWP{;w! zp|$p)cM23MKPcB zKik7rqsJ1XGb&shM{go#h)%F>yMJW^m?`XFcI4|~MzVMM_DXAjULc11KDDh)#nWw(10%{E|VM3I(9{E)go5O9GZ|ygIF%Mb1GHLR*L62-U~>@g)7I) zoZpxT%I|XVHnT6dr(7=HWzFPB(!5-}$Em!}Ww}zk&!uiQ^UE9X?D8j^d+!2bUE&C{ zX#vu-Z6 zo7uUxZWaKWx$t&^rJ379HnvA9!_n8gnk#ywd8UUs#2JP3#mCaVPUY`EJqq`7zr#@&%OX$)@pQsU+vLuQL?_I9v-le3*`f&78HBw|!Y3F* z{mB0a!?V@+qA&9R?uQr_G^pY$6PSly8bzBk4ApNG0bSSPv zoEY**#ZkZUoy7^qqQ-Z=)8`m+ygK1~wB7xI$`5m({>R~8okTdcobZg0xpN!pIJxtE#>iCice1}1`>$sI_l)N;e#Uq<&>^Ts4zZ$OJZ==; z54qZq;twHb!oNLaR>>C-5hoxK*F{sNKeW*XX z`Xok=@5~JP8uiVD4N&VHZ-E+;TrZ|lSKZnIplQC>+u{4`8L6+O2oRt z&rybF2T(c(^9fh-f9{?7J8}b||`QM@mSF!(T_{Vqphmq#@DAoARMwDuN=TyckxU_F^z1Ejg zNw%~9685iS{~7GRkNvIef0O-pu>V>1U&{U)*gu8+_p^UK{3YUiw&6w5)Mu6g3&eM3 zZI5QAnC?6mWqU4}8d< z@SjEv`qHS3k8nR)%IC|djL$s&s}mG@gHgww#+MZN??EeL28mY2_{kWF@d0-N zjC&ZzV3hF3{SM(HjBj$>$2e{|$J$S*OSrM5DVqG$8?O#*K^eAX5#Ak2m=@iFk_?q} zj-PK3rkjMD8H4=DPb0a%SUcc&)VOq9jKu2r{9Kxw{t}zw(QJnu=2%SR7hZ=s=X}lj z_1z7&h}l16RNmrfL)^;jMG=*EakMF(*Q`BkH||M4WOkjnsQ0R9Kk+G;4KtaUy)Q=% ze$uj<-d)iF0!_{`NAK&wg2Cu1jyHmD2193I+4aHeqirHf%QlvEMcYMxEn8G}Jy^Mx z8A#JEsCdr0s+4Gqs8>3|#ST@NcTLszK9@*v5fntG{eGuLi9V8ZM*?r;HgI%v> zOPwUURm+AuN%nx2O~@kIW-W7Ok?d(L%j`$8=d|pLT#~(}WmiR!>`g735=F9oTGkmv zvQM;ZL=ef2Xjvea^Ls6OGmK;b8J0a4uq+ge+F=maAyLaN%BD0OS~en^;`P_E*1jYw z(y}3aNmiw0`AH-js%6I$Nj5>tT(EVJI8)1}!`4Bffo1E&)mis|HEY(E^+0s6xJa|e ztS6#F#ih);#8_iD}6mEkdIVwaXhi?|qEfwU~k85ffwW@J)+ zU7{=~HKvz%o!L6^U7tQNy~U-yNp_w1bHsp{K4K5Eb)qG;ET*rR--l%DL`-&VOs;6e z%$HI*r+9Qse{qRsi_J4)28e4kySDP|m;!M?vpKo0m?H6&W?LfW#uSU~n6D$1_>$Z% zT+#dXBevQWp1&ZbM4YBsQvPDF5t_Z1zZ;J!OtF~QQX#>nF?&&LO8gtx55y#m8YQ?Y zOu;IPkSoCs8>M0=Gm?!|Bhph`4B(C(ZJ5;sUNKCA=J?Oj$&*9wf zVVB3$i=7^JrZGgkt=W;vn`4HGFPN>i9Z1@ZHKZRj`w5TM3>D#g?`@TOs8~--t`^~8 zcOl+h59Iqove>BE%+No_oFTeBntNiVh_5`F zdt%NMnYjO|&6=H4_F>EnvCE_RVa!aCUu?zuF!V@Fqi7^1 z*NFv*KgPJk4;~g6J6p^zv1IcgYZ5kE%7^B>#K73|#8S;xr6$GB6F(3`S@vZG#v}6Y=rp7K6 z>pd(mwo^o76_nCEP%$@lg;?Zai(`K$KJl>f*vrJU(=5$>Nb?G@-NUBFUM2Dexn+T| z*NTlEHaB*yunl(07RTNo7I|2C>@DJuW~)*!kG)MaS82_x^4L2>X0^q>OHPX2AU1l~ z<*|2(%o^)*&Eo3x?#M~0QN!&^d^*b%&_pyHv8$Il?*!#qT9`;=9 zgW_cm+a3Fm_`$;t#6BV_>Z~+tE04u)7BwE`7x%ar>0wcEPl!n#mJ#=qSm0sKxTnQk z9#$XsjMz^MB|DlmC2qSA^=@`<+;bvKGsl3W*c~Fp!#d(#6#a;yevSc`$G#+Xde|j# zuZTy7SgHIo@#eVK#M2&jf86WhB@cTt?yur)58D~{rr76U@5cR29P+S_ zB>~L~${I{Z0v+uxu5Qm6yFKCKCE|N#NSzEl2^F3^7ypp?!!Me4Tm&E(YBOZ25 zyuU0P?UvmfZBtA+uYIdaZ+4yLAAv0^7kCvBeM&o?6yp@?X&PU6BV>x$>^D~2^qj5e#zCGU3q;Wn$9${vU^9i#2bW0YM z*JLEhIm})ZG|neU-*G-k-p4W;^_Lqd@+o3+r8qD7LVLRWtCb30$1>!*no<2Su zY?~_2^2?BinOV7K${#hO{CZ3K1S$(%MPH8ZEh9Yat@tdNui25xf5i8ZLzt}=8M$AA zO(3RQtdH#Uu#qZT?)9*DCBCUWkxPyC+pYS`d}ga{iD`e3`Em_0*mFSGxABGYJ|`Kr^zf2Qwf7)on}WWBNGP8GntWflfdQ>)7Bj@&g z+_I6XM!xQ0@5*`^Je6d0uIyGrWhOJSb#FOBb`oP-Z}A%`U)SvJJ`yYBH=b$9_NLw& zFjB@%vlz9*D4DGpwZmvRn;Esk_kLsK8qFSb-Xh1zdzo3SGG0cXja0Z*S_8++i5|8^ zoi1-ArdwsA+{H4hRVK=yb4X^j%0wBZ8MVqpnZ%4{I-jVCGT+16{U*tJi}6fnvK&ne zBiKI^-;J9r=d+Ah?}RCGyJia#^Apa(?wOPyUD5Lsrpq~+?E{-7*K4*Qu_9r%oHEnW zoQHUGc7=Rcv-pIjgf()HN7j^Zr97h9X}K*4 zS4rCIz4{V)`UuxyBqtE3DH_0g;)|7CwT&mf_kliA; zdRSA!t+JaK%DEtMZNhDG)G{~Qkg!4SxY%L`D(+9%D7UO|vnLbol^a*P+1i8$nwIOYfr*1*|81`J)|;dU&8D1Nn)tOb^Sg`_^aH`tV?_!^*Pv_8!XvrA^%F) zE%$iXcL{IGVK-W`$NGJj@HaW?CX2QAlZo%hT{nZFHLp#zCB7%WBPN!k?}jG+-G@ab zzAsHYOoQAp3dbjYAcH+DHL=?xd&-%axKAc%*;CG(#1Ex|m|SOjv!WpJBRPp>baqH_ zK%UL)I@?tl*GC_ajTRG6hE*hbWMW-HMdCkXvlY*FZ^8=kv0SFv6A3Y3w`o=ou^Yc1 zZPKhV!Vl~@W?i;Vv#Syh%D;orD!}~(zxO{VyIFRfxFJ!ggEIYAs^4|u>jInoGda}5 z!t9^R`5tzi`cmHRVKMf9$~P=#lTkwwkIJ_-i^&)Xc0jXF9K`;qS#Suk(K1^C}PW* zS@+XN zH}%g=N>&3mShAb?S0tsV)x?l{ZRPN!RJB&Ky0EE9Y3gkcJ2xp^CEsajepS|<}b|wNqtr3MvB)ZY$cB+<*ND2V6%!BllrS0i6ND9V%|*3Q+u`M zYsLRaqF*TK??u1ZFhBfe>Sm)V?}{n%u)2)az+zQ>H%ZsoLV|xv!WZQD??peVgNKDs z{YsT}hOgo?yi^V2c>j=Q4A#AMyd8d2+fsD~%dB2kre-mtx$qHDrq0uhW;12#0%CHt z?Wtm7U0U{S*)g!2H2X)XGq6l;(Claku}vJ0#kD+-yUKF};NGdysT z`ohD822NJN4_IZHURV}5MdcI2y!=nuX~AcyMGq2NE?&t#CeBfv4_RzP%41&n@4?vwId&}?T6<1^Kj&p;5HTaD6uZ# zUttSsQ`yY$1VUP6P`g^BSwr#>u~6+NhOc(rT3l>jsKz~Jv70MK+ZU^QHG4F1hW$bn zy_sZP;;!&HLCbttYfz_hSTep>Td4|(q0jd!bH#XB|4>)VDvzuJvfrsvtyu%vY7g^= z>=KV=BxIL*WM7rKVlMNrpF&(Qm#Zqyo%+)3F`FZ2o!{;1 zCT7;ybGv$**^73Hce^_kzq*WN%F8G}FQfeKP~TEKxk{8^RJ=o}EpFBsyj}$p6E8^W zt#_(eX8YvfXesW}Iap)eT|L@pqsnH@b)vujE6E#G(^Hh@I`L4FD`t~gN(|QB655^o z2PL+WtV>)R_IdLCYOZDr`hT7Lpjtx=ngfx_!)nVjq`6MKf>a(?uM>mpwa_1u|ETW$ z6Un;7>af6+Csq75i@g{bnDVrmui4N(fho_Z2Z-sF^=+!V2Rp=?xRMk_rfgH;+bNZG zB6L7f%Cl;qX0C+Hl;_knn%$XSnDV0P)@(ygVaiT5>RBt^o%sV(URF11wj+N?$}ScB zoF#h@>@TWLv)e<*r~FmT@UW>VZ>pu5y_?sN^0vBPGozp>;ayetyp@VkFel|bb*pA! zknL56h`}!ZESQ(_ceQGVn=MV*r;=ZAvnx{$s8!6m!~?e5Qx2+KFOsZFJZ`@|<#RP> zr^P<9Ka_G}A#^wv{HNh8YjP;nvJajWR~=akI+QIO7Zt825hzI3O)RbTwHWk+O@`wA6e`c+uXG4jgEg1ajnmg@(N_)y!`?k=DEkEgw6lpV2BSy392{#Rq;*KW;>^tX-R zqn7M)dtv%sBl8=JeHvAr{(&*-Tes$f^aI9D4{Jz2Xw-e@mbIpTZfy6kW$A~Ff!|xH z{5jx?^skN1A1rotz>Vq0jO?E*mLG6;`uE08JRLx7J0sxH^q-9T@e~EI8|_!5OLGUF ztRU88zcJl3_nQ_AwBMZ`UiVzgtF`4zJ+v94EyW1P8*pKI?DTODURCYYPktavMt%9-Ym>CE`-INR*+0K?hw z`GE5rXPfyRHs5iMImE+UG1JX49`;@644-%l9S!DWkL*InOml{ZUF?`;Ugcq{9F69^ zn*GjknZsr7((KjrYaQpBUuo9Yaf@TN8IAb>m29$OqhpR)rrGW34>+34X_|eP{zu1L zvs1Gbj%|+f%zHI^IsIkFJo9zUvK((ZTFqmcO>lHO7MSV1tQ>Ah|IE>D4%6(L^rMc2 z=6ubjrC;W_z+9`@nzU;ji_9&W9Z9>zvDnQ;k~UKwx%6* zTw<1Jc8f!1TxO2d?4$Icj4RAJnhkcuWL#-3*KD36E#qqQX3ZW?@0-zOKBifO!Rrn@q3Gly#y>S)cl z!N{(`EorWd$IXSBy_MFQ z@q~F5F`QMKN)~54Y2KmPyugbxo-&`%?6QoN8Bd!pa6DRBZ};13zRhg4NGe|;o-zHi zsVu8)GfKaWf5uE;Mw*|fKbie38EbAc&-7?+@!Mw3BgS{heB1LwrbfcId^~^*UZS>1Qw9vE~g(@Iq~CWc*%sJ z#gsyNo2aZW`KuUvrI3G3i5LGKMSct2;q<6_O9tUJ_-K_9e+eR;9K=$hUxmPvXkEo8 z4|x<)CEChJ>g%^cEIg!0=P;1cccT&xE*pjT`g`j9F_iRsXOqrbd6u6_Xr*I?`=&`D zQlu7;es?MP9||P@BS2rjAy)LE5N|qG`FqyFTO&h!noRncu&V0er#iZ&WNphD?hr}= zYfxQYB56;XVDm zey@&O>J9nd5zE&mzJA}j|GNLge(UagR<9#;pP^pATgU33-hS@e|J^#jC7tFl%Eju# zzWx(izpAf7YesOd{w>la5#BcS^^;``?3;3O>B%%{e4Cs|`o8tG%3!5d&10jtREGF@ zh`TRQd%2}Dfa>lKbW43x^I8M?(WK)I@%5ifdaAPdraz*b(j;`Zve)l!!QZ0u^Pb?2 z`^#h6e`7SGc4;f4QQaD2eaAg(JhaMY^}|z@vj#oEox-{3GfEu8)zGR11`zy7QHIgj z`g4!BR*&_~@x&VWN`JjPzP-zB!(S?!RVw$D$oE>{n=kc*lU+Nka4#xh_53-wDp}Sr zbjX*uk}462tC+!8JyX>3743f(ZuLN`y?!}`6E%IuVc!&d!)a87P^p&0}+&7lN zXT%MtwYwEMlgNfv_~mQ|lA6MgbFrkpcqT@eQ|nu`KCyPbA-<{k`v31(?B8u`-;!G; z{C91Bs(PK+7N=^3ueslLa_fABIh!fI=T@V$5;I$#O<8l-vAG<=ZAY^^NKf#$WB#MW zSPrMS?(uOSL6<@Y`NUd7c-iaSq;^%AGKEs>-j@tpG`o`G2Y7kS3w^&4U%&sBaN zVu~D|(Rt^1Qp^gY@h}HJa~ha|E7+l{SmBI#6}{RmwZ=nB)0zib{t@LAi$+vapFtN_ zQfijI<)?Wpz0pJAnS4d=sqdAZm>ONb=*mTLE$h*!buz#AI_o|My(1OnPU-lDxc%W+ zQ8L)7pJ3(3eU-c>;pF~utUQoSs0?1e6p4IAuu7PSJ150gUPI4Px=SgS#XcCLbEHyP z_dc(qHLZIeQ*7gw{rNqSsaxb!S0$^CR`0b&Ez3U-BabznyZhvC*YU=6UlG!HHbtn! zCcaW+Wm4;0Tp1p2h*YfBN#PEmzENLJA#G)36H3hx6xY=EiAg+T%;Kvj^*58Hevn$} zP|1_I=U1@KHr9!Q-)*;%98PzRrl54Je(R6kXr|5oNP?6r-g?rk%}HJ1?|uw#g91C-FT||HQ&)A zj7w6JL+Rv1Qj44$L4D5(_w5y*CR??p^gl@?9PUpw-O!)v{+A%KOiM<1IG&r}duJ=| zyV+!)7H;=(=%q?b<@-M0vvLE65BLA&bSUmuNu*!d=u8TXIG=I%+#r4(nhGg-`e|-*>vy{trVu-blaU{>3 z!igHoI6(;5Ar*y?|p@4s8l|5U#aR`qQ=zaF)w(ZE;wbF2QAmir-&BiI%IfXz@A?V*qK_LZdWhs7pj+cZgY_x2}@~xe94Z4J9 zFV;H7Ln&m>R|>tg?y3LZv$MCo$f`Rrdo;uoKvO*Au&jzz7;X7emBE@z(A9yir&ilh zYInl&hPVsYP!ltv-BG19@!3buEk9lkvh8dclxCcEMdx~K;5+FWsoIDrn zy#DRzzT>k}I~7{J(KpBcng3Mj`-cB_^75S_|9`*LAAId#{rcvMbcgOU#bJ>p3b9e*VbK>y z4t7$?VfR+NGaoA|A*~eO;>f`9HIBn#Aan-8wF`R7BLe7$-4My|00!bqe)+lKqMWgs zaX906#;J@Aj7^LS81c??Zj4wCOvEp(`MK$0129W$0%HFY#(h91c4^GdEf)#EaM2ey zSQM~-Jg^?Sq)|BOVAnXH6fXhW#T&rE_*I&og*nK-P1lJT_)Yqt{2hLaJ}774H|SA# z?)naKSZ3fi=WjV~wW1WB+UoL(p@-9fF=3UMgr;fNvRB33_j?OEu&Ulxy&O`XW51O7FR?LHHl! zP3o46%^d!e+@w}i?0{xz&a2SL&wW=qxcm+|H}nhnhWb;%*9e&#`n`Nd(et?!qSUiu zTvVJojPKf{12tF^p?*IM4gW-agAv=*tAsQblCyuEn8xT0{kxL>?gx*Oj&pxqJ< zi`zIB?LqK{dNuJ%by$@}Qu<#PT!+-?joBT7p2FRV@^4X8m*=5Lb=(T+ZiG`hTk%fy zCqR0`Z-=1gbgSj3fyqD&@KOo4L${Bh_Y< zIRiQrmu!BE%tSi7Ri-2>k$)uo)M}ZMS}jvji)?1g6K;kM?faD}>3v!1=izu%iEP*p z*zT7pX+N+cNqZn=O4=t(8u_``0Q=+V?t!|T2Mh1?+sdtwDd~;bt^D3>m#U8Z6EttD z-0k-UQvL|((2h!5xfWZ|C%=cE@~T5#)UPP7t=4X2u=W7|F7;i|D8`BYqa^LFlq~3} z7ix-bng8|JPPCe~Tzh+M7 zAawR4oOHUBGstFZ=6stu-)QvqD%(rY8E>O9&#`r>s+4)Q4oUk<6&TTdZm=B|-FTbs zutv<_CufZ<{TN;Mexc%or{Lp_{f1JZkSgkg*^_9x}skUsV`lHU7R!%xt! zk@SAg8cFZjYZg()%?OJ`_mrF73rA(HcnS@*rc6q_?N`NP53&KaU=SPsxeA^V~#! z>ubDGpLlQJUZg3-eo61d?B{g$OWJvEzoeb#_DgzG=a8hUz#&Ojfz4dU{gU3V*)Qo0 zoI{e{8`&@Ey`BA%-n7{-=}j5JRtmw}ON8qg9{~1Ad5ZBlAieuTXUg%QBPdBo@P4k* zeo5~O?U(dU&t{Z-CS!B(4qS;Y2wsbjPDttPs{3IjjA`(f0BN7RANZ`wmBxw)4Lz4EuYvS>_S{4PPPs%H?UcMG7UmilZE@TH= z%&yuJJ`agdR}@BtMySb=3Bch%yTTPJ6kDmK?8d&pgDMES`VdaYB|H>QxF&Qrc10bQ zmJR*m{g1$J&ntvKuRn!9F@O-)ETpp_v_5pIQJOju`1``~2qFDdsPz_=pvI=08QK@u z$|pnLP&osh4W;nbKxurHaLl|(O(@@t>u+Q3cPQH;E?a)?pfJ12?o|)W&z&0<0c>Sl z6_%jFQZ~y3b#tHV;m^;#8R3+ElkrYvK=_leYEt+bYdkmBq_4E~leCjuKS?{uW%8Jx ziP7T^vJT;&h1YTTR-PLKE81HwSkc~cMdCwzmam9MfFemx?IkPPTW+y&ghqZvd&?z* z5z-EG$%^)zOGbJ8M6#l@ELqXBcbO_AxFRA`ttqaH*ukxwsou&O8F56?o^$*8yf`9h z7rG;ocBI?S=ZL9jpE(zw-@MV5IRGdNgAQG0bOYLWel+UOIN8f6oQ z6j}8v)<44f$5{Ud))xlpn+ECIj9$wnPv$v+bo0hN?Qf+4I8ETCgVE@QFx}GG^+z| zj*Juw0@HvCfi|%ih+lXDi=guc&?X{+D6bfxO_Vd%10%(9#xBMUj0YL}29va$aVldI z<6_3k7;j?S#P}rRON{R@MuetC8lrdT;3z{BGuAW4gi%Ou#$v{Kj2jpqVSJYH4aVwl z(jU**z_@_%w1~k`eejlhW@MfSVvG_u^~w`T;!a>M@hmV`ybN@TH-VLmwTvUhCkUA! zjLbZ7mgohXCC&hzCz^omBD{B=SR!H>3mJz2SBi6b*WybYnUS^F)jKnC7W-$he#4cYENBX3*f0j(76y$y4-K>?8bXLlzg|p8}`Men4=Xpsr z`iR3n;_#0++)xzDP!!9+w-Cv{Tg>ibsHepOAjS3d+gYa<$Lhtgdg%~~)r({G;#j`^ zS&DM+Yfx!xjnBlDeV#Wcq!wS2AbeV^>r-oTIjslTo^d;4HzT$mC4I&!#u<#AjO!V%n7-ukcGOlOb&e+W;qFA4? zig5;GC*yj??Tp=w0{b^2ea0%r8H}Bb>lwE*b~C2OkbV{8494}0-HalZQ)8@RoWa=1 zxSnx4V>hFSV|~Ud#u<#;6R7n?B4KypdtwQYLz3PTFZC8l9G*n|rz)BJRVjq~Qm7R~ z>U$zGOQcdrI{Z_z(k*`)>361a+;qbA4$9rkq8?bs*qKEkGx`u#*Bf=d+Y?Mj5v|<9f#JjNOc)oKvWzd{>?J5v5kcWnkRSC~7HWV;z-YKVxP+`5PHG zGG-2;knO`rbH)fxfpI-!<4BV3VBBxvC<>_>O`6?|Vhs7y8SBPy`i!d>*K_!G#%{(L zV>uVb^^ED`D5Q#U24gp)7|$s)u4mlN*v&ZObWVqHJ!AR=PKR*@V>hFi$muY4PjX^3 z5R(b37-ukcGOlObZu!q33vXxKe+JcS;|+wXZX~o}y{{%pU}hx*9@xi>Okl=ked(ke z>xg(P16$hRi4(X(;9{W>`%y~F&;({+5_2?x?=N8O5$*`MU%?#-m;R3ejDtHGVFG*B z(;s$w1AdKlMJ8uC@~5xxr%EF)yB>?aH57}+dW%6-zN=Bjpev--XIK>eUb z7|V>U#t!3c<6A?SrRJsPAIv|SyUY*GugoyNc)vow8o!Z#5BR<0_nF^Ueo_AE{#E|d z{Lk}WcE|Wp9hW%IzQ;8puIr}!TG^g1aAy}GWhx6UBQ13 z{%7#<;B!M3gj^7EQOJsryF#80c{${rkOLwA3^^L|eTWS84-F1Y3oQ?w5!x2IBJ}#u zM?zl=-5vV3(Dy?>4mHA(!g9jKgt@{l2wN6*McAETJHx&VGr}XobHc}k&j>#+{QU5x z;g^J88~$MUQ{gX#zaIX#@b|($2$vBl5!n&bB3u|pCG2Wq_huW~+>RN02v%{Ua7|9Y zif6>aA?LZU~1l*Ky%=Gz@AdtAJ;d; z9QZluryT`Oi@BdC(?lX@QZ*F zpP`}f+!Fea!naoX0KY*0Q5YX`f#0Kt;dgU60BDy5z+mYF*2!YvP+5xJIt++%N*bj` z08vg^2|Qh%2Am)V11HLA;3QcKoGj~sXUL(zDRMY)svHSCQ;r6nCC37%$??FmT0Q|&A4 z*V^~k58A)7e`AjgyfpBEz|Dc%1O0;gg$xS$SGa#fOhjSCoM`Gr_X1xQ_r}07;#e#! zBaX$<7qLHySK>A7NQd|3L>cgPF%0;ISOom5xEHt^Yn{{s;}fX|nw|7?0bQ8rpAgF; zBJuQsg3tYTUc~)$Ie`|Qf7O8<5qIF%T`MMq(_cr#wRFMZ)ZFpU<8RJ7%AyHMp5_`ED9rL6s(<$@i7JCV+Kag42+SPq6$5~8o#C0;0jxd zqYg(sev2D|V4Iohqz?jY?} zX}3yW_MwQM(cIQ?atBeT@@p?s4s6Ho^8YwCktc0PWhf8>C%alvzJa zyAj%r(r%1)2yA9f%rCpbHXKS}fyXR^5CGEbV z-B-2yhIV(uC41~v`|!lA5N~S!rsjWRy?F7ScK@#3545|FT_HZw{D5{p*5L=W` z*YYpb0PLXL<}(AHhWmot7O))Yzl39n_-nvD z@^3i00}|lAfn$>lw>^#HC6s?Tj=8AgONh5bylYz`KF09{j<0ci2c1~df%1A^d`TN8_G*MJ=J@Z~6XbjLZTNcL5!mVn=m_I|@e^EsxQ(dW9Vd3r8Ou**N;*$ib0|qaTj`IP!1|z>$xm07oGX>)ITOYjYs3&4IW! z2jbcsh-+!67>m1})8S5pI|c5UIL?A>8jiDZ;Cp~#I*u7Q8gR_SL2H|hI9xc+g?=ka zy#Pl$LOO6P#Bn~3MK~7YScc;w92ev0#IYRlR^Yf)@U|>9i#uHT`C|Iaf_y=KICZXB zqZc;A(>}dz_W2FXB}L;}FL1T#0N0}V-hk;d3n{J>FnvNtLr2rB>bACq#lu^gIwmfj z@0!qbq3g85B2r-}M&fnO>iQw|)pa!mwRI&0#Y3F=1*N4W&LIWGC1nMrXIRabw$ql!or%;^8A|Ox&l#> zUshCHG^D(wpuVuIth%VI-dR*qQc_!9lV$TK<}a=br0oJEN_s!{WLK9jz2`vTK&*8Ru%FhMi0e(++_rLtViMuG#ZkEgg_> z;k@+cigm7;3ujMma$Nw`2`H^Ew@T?7;*M=e5Cwg~>Kz4QPJx(j^^5#M3NN(!2>A;M zoP{XmY~Y+GKyxc#((slJIOyorjg6N7)cv=J5+OKc4=*kh&f2=_(xRgBn*8FjlIohW zQfF;xaczE44SHK$QCUgRkm9;hXE~W34Ge0OK#N;g)S8H zts3P!sdi4Qc1}@HT!!%^&9PzblUrf^8TlS=9olPQ){%yEkOR?hiF zREi?26yz@?a1s;&PHCeOL}_Su!9imHF~T?t7dZe<6XBpr{ywTVuoG_KB^dTU$EjI7^DfWD;1~`6cic zlu%KDR0=ph9}R03>pKLd25$l2l%*&n4F=~gsTGkLLm8bft&OfBZLRYrb(~u!>RX6TY-O^LLil1*PB{}4 z5;zHp%0->Cu&(L+(XEXI^&qZUUNU`Vxflq+LJXT?;JCJ?^BX!`!{^O!cF{pO`d9kx@ zNO4h7nX|C4ytuxoy11sGyu7e%NO>`Oc)^gu;<{>_siM83jiE*it)-4PuA!~nHL+=) ziv}fch&5u=c{F&?@KURzGWYGdUIp&CK5{ST46QEKL%pD+P88M@<`);&JIiY^j@071 zHKeAv7AJ3U5!s=>xVpNwB)_!Y8*c)&fR}ohRVbLfX+4{>d}lGnn!2*OIuxz| zr5hq@i)x)^HMK=$#nsM2j4d^#8172zYRZc1OY@8KOG}4TLta0`dv5E(a7YiMk80}Z zXm$rUpsts^{DCNPKRg0@UdQnp$nVv85eg?5%h zbI)yeb&M4gPA5@MZ4TnX_0&eVCmqWwQ+n`{BIdqk=&4Xp;^kD*Db_`7`gFR=&1(>t zh;%fyw>OC4EtuIgH6r^4F~;R;9NpUHvIvG_?VauFm~Pc#V(WyCwx*WZtT9teSlr&> znwMAG+T4s;2}XzZyrC{kXqsjTiZi_3nuyXML%khNZA0@cQQh3!I!m;-Sz5IV+uAU? zSW~0MiF4X8Q5)VU1`cYTKD`OE*QSPMPauzT$bVczBiV!IB9u6$4&wBNmd4h36Ho4<{%a_X}#dzjYQQvd2%yh z_4Znr1QSt|4kew`0!z(JWKCHN7U(cA^O=M{aFu!DO`^xp?EULH}n_sb21w(|=1|wau=Ewo$J3_K9;E zTEEu&o5wi;OVaR)`e}eTvUxg=S`np(=h8i^sXUIu4Z&V zJ!5V^Q8LE0sN=-Y(-*e1AolQ;tm_$e#RW!)8KLrg?2R9tT~pywi#_x(?-EKU0W>Q zgytsj>c;aMaJMEJv|HEEf*YvTh3!LK9qya9(_Oe-qI)`lKrf+l&i9T_c#I*eW+(Mw z4efJkF?Z6{(B&3G+FUO8@P>Bnz(o(k+`RcsIG-lC+RjJO+Vdv0v^SjV!c?oy)s7RJ zPK43ug1EyI^R(OZ{29BjW9+#YsAjvoXOep)^2)4{$ld+D;lCK?*E7=BAx{y0J)09^ z3~%AW|7=t^X$jq<$;8&yQ4MXdNRQFrw?&~2>Ndl4&-mm?k;D^bH8fLSa{Ju3^kTTX zb8t8Jkm>XFjlP)Zz0DJ|Ja_!Q_xr+k89@xM<3X41{l#$W!pjQ*SVfpO6Sv~6b*&3Y zW>M=F-V->qb{NhUNOfQ05vFGljX^pD-I5s1?sbSY5@<4gj+NE~3^quT%rK^59!`}u z*93AYzOcVy>Ho0z z9sp5Y-TvsA0y7NK6;T1ljs=)OiVc-67C-?jigb}G0|J%^Sfa+>yI_y8_rw-kV((EC zWABMZWADD-+UJ~^0X4~Y|Mz>}efRy*IcM*+``T--z1G_0#QEu1dXfx<@#BXXmIhxE zi5u~$cn48mIIvSidC%q80U=Y3+Q*~LH zVg&Z)Tk!dbJvtLwBgB`aM3Jdd<^Dz*_;ey_!KXuVDNml_khh@Q&?FQ9A&U#u>A6;T z4rB(XSeXV8qzJ@eQerT4uRM6DAZk%gD&)9;y!2cGCJ1k#n5eAqoWxYf9HA+h$RGeJ zKNke^Rl4qDcvx0&dTKU{5{=0rCxIf9Ijtj^8%3W-IbTzQk16hc@$orH15=r-1%eRM z1;!PACPa`PjRuw*KgJ9gg4{F^Vg*pgL^?2On5w}4{UNI9Xeg3^iDo6H!X{P$*s8TQ zHWsrK!hvuma>2TxOUj5(FYE*@7E~VRmkV(=K991%AWlq7N;E(Sjl}MmL`yQ1At*W% zwMtD+r5e!WVF=N?qG=k?`yg`U<>thti{!2Ah)E!?T#QhiKjhiuj;U!z$@unCF@~%@ z!hs>E0v-$jV!NYKq0bq>p%}+;z#PM3Cy2oqsfN(-cwJU{QmzpMqzOzzMvO~0L<`L{ zxW&4)O9d{C;6VksNtq;E8ls9-3I>k5qK`ir7@C>PtWT`Sk77YW$%B!!5JE`?l$mll zK$s(m8W>m9L5nCE||IjEY?;C_DfHV(-}g8)8kT%yh5bF z^mK^akfS4+s1p&F+s`NxPhM=abV*8&E8xeCAy2Wyh#c5s5^_Hd2*}DV%t=k@XA~6B zF_N-Hz#8Tm};w4KQLwyx3%biB(~YCDSMaVK!s%+|>BgbaaLx znOH7yVYH&aD2Vu1r_@Xucp3bQY1bUhBe_W(<8-;fS$Ua>q`3;P;M5#rAZ8O5*gY$U zt%!stN9AWlWwir77+f@CGS5I}GG|W42HGVRFb`_L<`d38H9Z~F(4jaRo*YU2H}qn7)`NG801USNCx|4$SRu^p2#QxKmIe z6Q&T+#k4KGN3S9Y5R^y+!sjf&;xR}BCnH(Goo!Hp1qf~}7MnG@RPXM*v6@YA5SAfN)^H_o^sw15Vx-V+MI|)Bbnm`{E>OwPl zcLpsCVAEk%e1FcL7=tdLUs3{&qwsXjI6b7R>_XlJBTyO}UdSUnxf}U-vP6lU;&f@{ z6>AYFNPnW2@kPOcmth23nnLW zqCJK8>5YAu(=urwg7DKJk?EiYu*nOGStP7{s0eQsZFB0)m6+~Y#vtJQ&T>P!*Xz;z)!_y*!w6lHObqv9M}kN<=}dxm4k{c zsgQ|SZ>{&ov3WF>g9~|oDmKHpA#x^&h{hf*P7yWn8Vc#aA|w)mSgszBD~3=aV>@YV zKwM^KRxT{#=^+MtRCp%K<}V@(x*Q+RPsgGo1NM&9QLWk)X7@|V4P5X?Dfn@KsjyrhzqNi2>vO*Cx5hMGw`B)Isb6g;yab>h_?6ATxf34@9#Ke0r5 zI}P*cCtSXfOo=tb2+K0KsilxP3;@h^22X6ZXi%c@4Lf;Gp;%oo6Fm#!a$%W`hMhM^ zU@1T}<4qz@3Q5n3C&5Sn3JL@Xd0Cm5>k9%Qeo~hO!x+h6qOLCXqdp*$G*i|dKb;qCp#>R$$eFDN`gaU_^=1nVt#j0SMQ-vxS8Vj-S8PkZJ_}y()EgoVB?v|r z*v~(on9YHtQiy_Jh2(z`UcLcjD*PxdzammTh)>3*-S8ZAl!yW738@g`Ksgn%`Danf z*XFaC{Z(lqIwAL^CVsro#rMZ&Enmd77y&c1^CnHBmWXSWp9~diWr&YOKnx*XvSA8g z4q4(L3c)r71{sy5r)xeGyA>GQgwzHXvkH>7&(T2Z32}gVK>5_w%q^I?n44G6nKOg7 zD`YWd(-R8=@x-v*E)!f!>!&fPP5@9ka61^0K*X2qNHRx%sKOr0^V; zWe+GPFwb>NipyqBw$8*A610M@8h}N*k91WA{Dh9m;LwjUn4=4cv{1ZYanSdP;1$HR zs4T$`L5E@q254y215;rG70~XVmzqvKo-97YAfN+bTOco+(N;BHndC|3UrWMQNledl zLBWG=WBR(_jc5DWxF}&Iiy>BIFCq+EdW6L|5d!K&KB5rI_RVn_{Qf!On3#@}UM%XQyvOq4+fF`l8e_5v0mKS1gDsb*OX3|-S^OJTyewEH$VkYqS_fk8=XEvS zY>|`=BNBy*8zsrDR~0_m7vLsF0}fh6wZ?VV0nBZol*P>k=( zHw^tVi3kgy&W>?2fqckDlt}8hQE`8>E&<6BjId(*tUSmL`WovcAAZSI#|0ONLtp16 z1PY2`WEVG)2k69gBXN0FCz$?;jYIF`y9Z(^EQmUeH?)a9kSl{SMxVrNh&nD8+e(4nHKB=^d7NiqAx5ejklauwCh`d5k!iT!W=A zrubt!8>|}TL2)@LItbGVIa#`_Hv~0!155c;QYB5%;)7#ro9NUy^1Q3ue8qeJf)^kKALrb~k8nVNb2MFnn zHvRBxQ~Y!g&g|*v6X6Yc6}83+x;T^NUm!lq*7rutYbhOro1-xuP#pWN-QcM3&*k zvm3rL#A86Ag6;q{0+Ry2RLY0&1j@V7RKyk5wRlB36Xps|Z#Rzum0)`X&wv=WWlnyx z0ndI(O5mGB+^(qycJSt=VwYyc(7z0%q~4x?k@TZLreX_aFgN5Yp<9iiFx}^r2NMSZ z;)F;do&XUQCn1C<6u!;OjoC>EO5~w5D`F53YZOo<7|Dn+LmB7yyz|K8X+aMn)!ukJ z2wR?@ZSVRR*dM~S%LWqiryt6Tyo)NN|NkO*24 z)1n10bw9CC!HY&3`C^H!3L(sX?WYrb*tWzK{0Y@P@{~tR&j77Mz;P&#R)8_m5IQe<#~yY64Qj4SNIc*7qqtG9y7J z!niCyXuUm+gFqSbSWyl@>lio-K`dQNie+wC@34-{*b^^V=sf~3D05(HP8M4t!<-+d%foIU zwgTsu*gsE~OCw2yGY!xPtXJa25x`*zf@q8sth@D{&vx$Si?+2-@e*PCuQ5*{F<;o@ z`>7P7fKS}#FQR=WV?zC3q%zLjIBKib9V6oWCmCKC4FvaAPL6_-+O+83Y)ho{-`YB&A1=$4$8>J9uG1haj|ji#g<}8CQHR(fXswKPLy&W7tz$nI9Yaj zq4Ayrzs$ml{l{+x_`G_^YR``jhC{*0%O8TrPbWBlMZqPGa=}}kkqf|9t((TiW-vX8 z4o5*g2|&{d>0lgI=CX7;)()nOVS@{`DKs;QcG8hAQ`iUsVFV-f8QRWKO@oro%V3*D1;Dm4j7QJ<}@Xcj%oP`djh%<2VI19IFa5mX^Q&_G( zJPW6glZDgATw_1vkb|?zXa{o2KXn? zXejav11tq$R1%$MRQxi!vF59YLR^~Oo|I9#_> zK1~;-jl((WaI`VKLTx{pN6WuXAIW7Szf9b+@`>^rmrwhbaZRZGTu2!31#Sa;!9vWi zNUcr8Y48A64i>}^PVRL43&IKTJm!Y#fLe$paGn3Pd_qu0E^dB_19q`F24y4yQZC0H z)Waz#EdwE$h#iaG%0v%QO;Qm*3fRm>ST{x`{aD|pvY6EC)UTgz8Q1*doCA>$^)sdC zDS>D*3OT^APj~Sm$6StcGNyn)#MUvK(TVs(j%yr_+Jdj+M?I9ta!bLv`y_!9sT~Qd zB+lpKI`|`1B5uW@vNBjL2)q0!Nk(3bmP0;H7h;5gilgeYIB5BCKF0kWf$|B5*qDoV zg^`L=j}?37<5)cII(>!w9y~b9*A)i%yFNL5eE*KfHo4%(BGm=ZmH*Q6WWg( zu;}+$jaGlp$<&-gu9irYCV1FXA*Urhq$X;q#L|*MgV?i^X%*X4iH!sEWUydFl1OX| zO(|*7QWoyaDXQ2Ot(Nfb^}>6##E!w& zQX*pjQ5!x?rjVG+6;d-Zxk6$Sqf|(%*aS*UlqT$j8e7|ON)v_5!pz)EVPX?wWulZS z&8(#oYiIoD6e=n12rL>|MPX)b6T>GpQ;Kg2EgESPgY;4}%CfD*M5RUvZBf2bSyf?U zj<^6S`9CvrCH|RPa;P^&p?nAxlA1+(SUor?BEm1`fcqV7huRePP+ChQR#YFEN@8M) z{p7;*$fvNyrirnYzt*h=rj)fYg0Tx0R-C? z+7?Q27mTSANhK6m#inRJ5}tYIR4Of1Xd7i@gkiv`8whHqkXrIhVx2&3LnqJ+ zG-at&nsPErR1duYH}Z5uTlxO5<1BfqvEvy2C=KGE)y|xwQYEQki_c4N=19Z49F(k3 z0edK3aIwy{;~W%bmNrFYR#a;%P*EB4*c2^6^YB!fap<=)N1NiIASVYC4(N0MiltVB zSCAHpqAsFLDF=m&Z!h0UN7j8rVM43b5)?~*bew=65FNFadL3iO6JZKQj=%(UtxV2I zq%so~2-$>T2ygPp;AufB8b4{O6E|Za_D{h2gc;|QqnM_PI4w3YbX)Og7p%0 z2jzlFI8Z_dKBXKVepP~g98kED9x4ZODii~c2DK@S%BP{Kt^Plfr}^M~6F7%dDx{Xg9Fz2x?P$GF{J|$t6_=5wu2tz6>RVW-CQH{E!S~V4M2n3m%E3MHA-p!tDbW#YA14IH- z4nPK`VI>WG1ehTJA^K!IiWs8@noX1xosX%ItH3iv>?lw=%SYy{5Qi6Nf#pg4eLx~S zd9+$d5MNQ#C@LSvim$j37k$n%8NN3`W0-isY%qsl%0;D>HVO;WND8trF*i4(*^0VR zh0zYeur|RYD>XCcsoohqE49WXRmdiK+oEImFQsXxcs?Wxntp5xRZI+cfXVBa64CUI zLj*x)=4Qy>tQsEX)f5W3xtYq^1f0smrs!9ozFIXU@43pqZURLnDtaiv{7Bldv^1qz z(8&?8G507qIn6+h2sOiiu_?L)E`ukve>B=yRV|lVqaM?!OOyteIq1w9acEAY-WV;B znW<$`YfD5@S}9C0ld(`|&WSN%M}o`XHdV-+fi^-QI>ff0=jI6;Kg_-MMPoj1$a>rN+U$&?^YR0`n`E%0Jb3lc3&OyGqqOo8~1k%Fhn z9C_Ll+ps_u*M=mq;?+tp5Q=BPfKE0FrOc)YIu+WKO%wWWrJ%`I&~~6<*(xgO{d_e| z>=YIPh^7tz@gFU=z^@Y8Vri+ADZz0pEp3a}gL})MW-XP(6b_{s9x8MAR95IZ!Y*2Ye^TlQ@*~Jxr2zU# zvlU1Wqe5X~;$*_QgLgs)P}Wf3YHQNHslD_Eomr$8bI^_n{M00nrcJT6RLb|32^9n& zUMl>dO{VzKTR}P%$>;QD3LpmP1xyNd5{Uj1QhX&+I|i}&D7;wA4w|B+rp9fr45X)3Y;8ayDEN*G?$mZO91J{)ts)LFT%P3$n6 zpHwZ1N^wIcCokggIX8S1S&9ezT_XLonD20vwuI|2YX6afsJWisZK>YUfxF)F{pOAL zn{&DHD&EU)9Qk=zto(%4$N|wSrc7Ab@b`B%C$_I{x!m&o@|}xor}rQ4qw07@_M&pT zw9Fl~dyHJxEW|nU*?^-{mc+H1xS`VEg>SmR;cqYbP6@Uz{G zrG8CYIGOys>vZF0M^Ft^P(lx?ogCQV(jyxxCN{>11GnJQ}RKQAn}#I`|u%F z(gI(raFw`88cWq7*_m_@A0Y{XEnY7zPp8<`I-v0P<`L;gMRy;3lZM zN;_)_n<2@Z$4ep3TxGy)^VppwavpDd`_Z5X0~}MgqWFGLn4!q%?=SD zMa94ig_`6v5~^a9JX8#B0#1)$nB;jzbhCH`o&?5ExOSC?y1t$xm>aV2&It0 zp{Bt;VnNmxyxBtrjnv>{E=*TEs1ooA-b(T}WOajwV(|brag%aD03kX#_0h@0hgt&t z`pj6k+{lZY_W5u=wLV<*>WedE2;&AdmuiQS1s9Yh%7_QU15rmG#t`Ss*`OhOxByVv z>QjgiC7&bdQ^>@Er4T$yK7Y|C%2I-?`HC2P6p5;%uOYS9n&rUy zM8u}GlA0kP5HwA;w@R4pM3hP_t))ijmI$#K_R7U(2o_^A56pL@?SqaZ_=XdP36<7R zP8fl(2TX1tBqIQVQMyQ1e6SI~C^!%UvFKZ*7J~r*(Xqsq7$m$ysp5DNghd z$-##*my!(=B6D$=kel^}FignLBGFteMk2RyB=Ym3`$@Qvys+eDaQ z06~`WkwH2Yqbfj~2&4|d52JvU4W|faHULm5iX$iUniEaIOGzjmnKM~>SjWi*pnrhc=3(^! z=GRliunWPtEo-7y=w4`$sEWXfMGFbhIruh_ln~AvrZF6hVPrk9g1EtA$#~m|5QTzx z`wER&DWzf{XOO>?QV2dWt1z}erXm_q1h-^)f}r>;iM#NF%>?-3>D&ZJBM;*>q6gW6 zT_Xe-=L7gL&3nP@iJDPm7RvJgDh~NjAMkPY9zG^tfHTXDQj#Ab{F9VPV6K#C6jK_C zXI2+pFQ>jHWC&`ym_OA8BUp?>tQ>g^5gG`C6{tf1AP!Z6uNRYHi;7T`9aLu4Uno_4 z8|)BDrNQ)|EN_QUTIeklWaoehfpwf6Y(&%$-k6|*Q*`q~@GT810`fXC7FcBXLF-prKIqFHd!S`S;gfxuE32AZM~6dhecT?Q(UV&#DW znIDrpMyNH!Rw8|+1t$~35LE~?0fEb`ku`BF)ENmaAOZ7PLYRl#FO`@xIJq$2BL+B` z;G*G7bG|v=P*O;~poK!RPb$rb1O;+Zq6BMrp-Bpr)dMU(0zhFDV5l;Zh%s0OSasxE ziwvwd6B17ZfQbneXym8V1}_DQIUy~1D;cr^4asTQN1r!e*d+si5{UH@(#y+-!aTz8 zE`&1u3*91kjT%l_flnGo=25JVtTKdBBUMJh_$ZrHC04{7O%&sjTg=r0iOl&(5F{x? z%z@luRrpw97xDcg=8Rf{5D*6XvPK>Q*;KR;^2Xi zgZws}Ihi}?Pk>l*v3fsfdL(LPXhWrPK57Bj zjVWJcepUhhDxbln^35uO-v)XsYo%01!v+vT3G#9!n3nUA<=YTb1z#mSzL3t~K{A5} zsSF+@GUNcdGRjX;&PTmrhzWt*s4S#2N4CNLriC>itx2SyU_0HyK{ zkS`phhA@YW_E@}eVH-YR)qoy~ z2P7Ok3o#{FnjsFqB!LtvmNk`u8re9QQ3aUsmt4Zk=7O2c1)?E^QBA4t68L!O6II31 zDPXJ#jz}jOk6;;r$pPOqBs)-))V^CzTy~hz>3Mb}S0_M-X60VB=ES(y6B;u+yW*oqW5+z)9ebC-DYPYbUC^gO+WhCWi<)m?3Qwis` z_iMF2ig9W;HLg=uvy&t`HMX+ive%?UH!POnTbZ72-fkW~-dZ0weBXjAS}Ng+78=9U zZRrShu76<*bt1kjqV;qQ4D1>i-YqoDFC+-pxg$IWx7qeq6}s?I;j3LnvxaDD>yiU)#m4#oJqup3X+ zI6h8SH#Pp`7i{naORftYP1T|Dx&731MPVW?9|JLo$8FU(t*pjnGHM;}fnzs#1E0Wl zs!oj!@N`3>IxAUShy!|R&=ot8?1o-+!WYKMjV}G!IDFrQ2*G+Vc9XNyBrXk`MtN z;n;)DjlX_uD42((oUXi8iXkY5?6~aj5=^+q4?o;R)HxZybP@By{Q^2Vu4I#Caun;R6^n5Sulx^KoJP?a^YHkx9A4+{lJZe-VCx z^nc@l_N6thK3F7aRr*bAlO{iU$NhA7>oI%o+lxP1#4Vg+In{cD)feuL_TNqJW52?3 zON&!yY`Wq@miQ_dhp%*U+zGswp~03socy0{EAEHH!5=67uk7m`j;y+WoYjBN#_8S2-2dau|J7Z* z_UI|kkF)vvEyQ4ST%&)!12_%Q9sg>>_IyML{@f1fe{KK!c4QUtuVwZ3Ti}%->qh^4 zPq{xu|L2>YY4Av#_(NT4I&04^4pHaF>A+Okl{;>d5ITpBOP;`7)yen_Mpiyf@_^wc z!AGA>QuCMDsWWf{PaU76j#Fo{8(fGD57rD-XXU8Var)a$QqAbNl^X0iH!Dl6qcc}- zk`__Ou0coxF-vf6x>7rlp9SL7`m3=hT{-6OCW#JUmy4-!v4=VrQ-`_%N^Rh#ri0LG zcHEYM`56U=@YTW{B08#Bg?U9kr?^R6g|qm${3`{hiObZf`^61RQsWw4G@9-aPQg?! z+}Pi2dKc!8o0j&xWZ(NO1ViiL79mtpZ_oiLo+odhyOf>IuTd>BG)9~ zPxzpRo5YcyHF3fa#p{6Iq)at`y(mOBNr#W-d>qCuFOz(PFeZg$;Sd$wM`9$6NSb|m z>i_#3CEmE+mt;L41ahTes*XkH1yTuM1frwEJ`&JiR0s4c$L z{1gu1k6g6Y*Z{w~c2e%{Gl(#efsyUH_v@LlAfnxDyH3X+ou6b%@q${!_{GGMfF9GV zd5kWGmv&=7>M=ON9)lxe;gN2521G<-24^UZ5oTMS3}TEH9?OTgWhcg?g#Y<}k?s8G zQ)2>pTtxH`njIpKou3)FN#)R_#RwmK9$WnDOm4O4EB_8KipO!W(2;PHZ6{nV&oPlF zDT!Uq$%T~TZDwy+Sa_oFinyJhy zSy)=bGwTwd>TaSHFQv!$yspxVpJh75-td|K4aorF{3H z8WR?5&ThP7^?~{4rUzJ>jBmL1?6MOdLTeW6ef{E>FDDMVbH23l+ynOCY7b$mMWybc5#OUu0ix8&~4v zRmtsDlS8d;e3;Q?Y<$(-=bkK^JbUcrSM%Te{>92KcFbSi{#5AB(eC|Ys=cj$`sMH; zb=6lQ?&)qEecaG}MDg{T6QaBAJv_1RwNCqYO`Cpu-?ZjItDV=MNZRwo`p6-++c(~8 zzO=z_!&YprW|sC{-vcwhiOhTVLb_>m>6xTQJG=s(@4vYtaY*pVOAksShh%+V2;&yxHfQ3687R9q2zi{`md5F`?$){ru~Iam|{Sgv{K=y{kTZe5b%c*Kho* zy=5RDAtg^mpU>v+!atw#|CJD7IF}0VgTnhY|86^ve@E=&-*um|cM&#|(4Tt8F7|dw z`-8n-NvG4h?bd+r=xx39>|J^{x-){*q@t(l+nez&)qWj&Lx1OpuBBVyhssqcnrlzko+37QCm;az!KTX?x?!)o85jOcpznQ&s zleb@N_L#jtJ=l5t{q2j=Z|WW~|M2_T6Qd)t%#Q9D=U}<1gTI~IHMJQ)y{jDfbg>9Bm|dl9iGxlFHIh=@-(C(tA>8S)^>V zY^Ut8%thWCdX@M`nocYHdf``yA9cnS{C>iZItZpLPK#eSewp}*f0T}Nx}NwI;5QRL z>X5VeJ;4tKC{BZ47=9T-Ivwhc%dxp!v_Bv1hsB6XM*DR_`;qMb{{64R0PHbnlLN+V z`KIv}In5{F6t5kA-PKa=S0h^eRqhFBS1uA~hr8m;Wf!DIHyV{%Sp{n#@ST*tBbrioFJw% z>X|sLN@ra4XW3bdb@En-B0-&U5sOY9r+gwOoajOvjsBk}&W8dAI8}=CYV7261}C1E z)d61qB&)Id%W)k!dwm-I6nP=A5XaI}mFT=}0_sAiYw5IoE~jQC;JQKhsU?OM1hVqQ zmh*-VN}GzfhFE`HpB69_N%U>*3JlVjW8ppk)nl4T)3e%pT~n6PS?^|b|NG<HL2>Yil;R8nq&Y>xXu5+}FUtKgWw3 zV$(V1bi56@=$MaAm{U#Zj)6p!O#MM^2p3}VXU}n)JW3~Oq83rl{uK@lZHdB{vQ;2->yNe+z=-SRH{a))W1|-KI>~51c{Q;kMgY8OP=?53SpkMd1^twuIR%+Haf#`f}O^r9~Xk!Xwc7E#HIB7=%F*+l$uVW6K3ev zfF#Zxl;DP#uIQggjO_rHCK9m{SWnU!YDz`@m@(_ zX6=oKi&Dnn=>s>>v=?yP468=4pQCovCc6KEZi!F>FXcxA;aS7lOKtvN_Gc}{hDgvG zvFrc)_y0Q#IM75Zm2#SrHs+>gjYhQ_^}<4;kd~ITeyb^I{ZcBCXw5ZdrY4OoWzy;< zoTj6xssMi48FnM}f!$`?tCI8801bn?m@`d`X&z3}4hl|Ozy zcqDIF_al~-HkX!E8LcUi|Dq|8?JdRrcB#~^DW+US!qRGuY#QA9nR-K_&{*gzhOGdc zCZE+v7A-fmlSW5s?KC!~@F?w6-Qw7Xg>thpwbmL-0xIkjU6K+Z$0ll>HI4*P*?oFx zS6fR{lfq?o4u-{By3^Pdmm_6lt0MyZG|p8mw9Pd5F1d#W|Gay`+gu9+f#B5?A1+@r zLL94^w42|5p+>Hn#+2OLuCAd*p;+D}%b@=5NS(SPefB9SQCnYAmyhm*Tk>G~RYyfe zs)HiKTKM^UYF$13J$zh)QEP2IO&z|Wj)rWF8cNI3xEE4WBB^bRc!>!oE0I`%P9!R6 ziA2J!zpf4M`}la!-k}}Czu9%B?EZ*m@6LTVTIna#^lL6(y05XQH)O)*%=_GxU7l6f zjI4ZkeX`6sx2OBV;_=fLzB#gd^jEH_(Pv%u4%;BR)cPFW4s(66^V@|bO=NGYMz4OitnK8M>&?erimRQ`J;m;D-3=l0Yqr`R zn7nGyh?m=kzX(-qDv+zcdOvmhmhH;7obRJeUuNH*Uz$4M$^3k;GW{q%Rj#G*%Negg6cQ7?u`a!gf0K^kB&d5Igf}wdoosWm=~zZuPIcrC8vCNkbv$4G+$A_$^`PyWfp0c8UboL{qm?F#($|!C(sa;- zmWGrDjS8T}daTtaW!{Y$wL7|4xTQL78CxlIV+v~%c=GV91K{k~HzuQc?&^NIa#xe4c^H@$4psmcVK zYa=Xh2?q3e-n4Bqp8IY zdc*D&Y)wf_Qqw0{Xo7ccz&R{N{nHtv1tdT#9G*rT?`D_xRq4K8?^Huv(KBkEcc&$hO# zH!Y_{K|-?I=Gbc&XTBRfVa4c~(H)(fTYsGz>S~wp>Wh6#SDx8DY_FnuElslb^qE=9 zFMqSt_W8(r{ajM(&#k^->)QK~1zG!!YBgUzf8pI&)3!&u;G)hej#VnUbff(O*WBp) zx0eSF`pItB)4g?vR(jX;*zG#8bB>*Dm?8biqi6pHC)OR3d^K(Dtx8`FsyVc_-SAP5 zdv-W8BB5LLw9tYUQTHZZ8~MYnHZ$to>GSH~ksr$*Kdxa>yVtkwZ^zxc=(0b$>Xy4t z&ks8BZr+)Rf7~0`sAOE3$cSQrsa~HNm@*^o6lk|eIzPYlr04<9ZaNNIRkiYo);diD z4Q3m8s3v4dkS0LeP}6{D#oW$l8eJjyQ;y#qvAKKr^d|f6l0!ajP3`T!?KnqOQ`41-tSJxIfa8^d7laF% zjny=BZK`zzg=!eb>nXA$aJ(=Lc%JA7$7}u1INoRS&aE&|8G9T4_2Xqt50njdJl&^g z&HW|I_T6*o-K}1o@t5kErDosllxpujZM(_ObBpfxIN2|;#&FLSzn(}KKR<0C_iXT5 z|6Ij^x0AoWzAC8cjNa?ty`B)fA@q8HX|-7+2NaxHaPQ)Ddq1sbc9Vb^i=_EqyZgqq zPw4UI%%P{cOz%5##f}<5iZ(y*nfM~&*|%RP$K3Sa-+hAL_tTq&);#a@QWM_Ly=6#` zDL#M9to5L3@+3!h*Nn6e=6SbP+Fp9ScE8Q0tF=6O?lw6d^s3GHu4|5WK6iA@PwZEIJi z$u70gl$h)Qdt1V@H&tBI`qh~Pt*wA8O)L}BRAy7^kD2H4iMyTV^i`|{+9NBroHvmD=l(|SKsPh>T&E_!uSjXAtV9s2Z9zg3+&j9e6p!_2o-*bY1_fI_>5=uW31@=LW_)=LZcR+06c=u9wMoDP6`d-H_`3 zOEvTNQ*s+#ALt%+sj{ZW%hTiI-yJy=8?24^wt?Nvwwe<;4Xs^j|L7CuTk7FE=~!7a z(~&V@T}xaVnRsmNa6UZY&S}^9KZAVltWt8%gUc42>NT!@$bTiR6RaL?gq?h)sH9i_1~ zH50UxDiXN~%NWwG9wsFL?cFJD*qQocr(c`Zx8(|L*0NSRF1Tu{=_6H^$}2gmVAUWS zMF8hlj+a@kD(Ty{YlE4$>e;<*bWIgGy~oWZJo~Ik>{Am|8c^yts?9&=WqNwg0cj_I zvKbeP61f(*SUXLyCQ$T)i#7XaT#Ww^1PvG(FUa*{{)KH@J({;3RzG;{?^$ivdu;Ci zyQO>PiqIFo$L2lg*wXcUz-sgNNA9_57uPvDBw|)kt=_AA-8+7_Xhqj~H?p^H+w`(< zb7;b9{Rx;>umKkv^c z5C6C^s-|bFZC&R)imWrT(UKC!sn@3|oE~2fdpWM`@Ljv5lfw?yI6X0EdZPgubF05} zd=z;uF;2%8joaB^Lt#SKz(t*py}Gx!d)G^Ir9px2u}^bGdb9>&uBxvyKO!JyZ2w z;ePq1GjEz)sX2DRD%Bgi25nd0e0A;XVZqxKeM6G^whde7e?RQO#({+wRGwxTjz!v< z*Da$i-70%?E5v$r;;au5_HILVo75U~eY#(R)O}MYPCqpM!rWSGEMn$8TC`?Vzu}eo zyKWzt#yQPc{n&o+bNk_Sza4#||B4W;`iFnG+ZctmmI?CTK#cq`KgYpb2Vz4 z-xWVaO|KFFobyGAWs>s;Wc%|AN#O3UF> z%i^S)oh;VBeKB`~q2~*oe%)T_J z?e%Wk*LI)dc+E*NYSs3F$6uYi-%|3&^<5KHCI`p2yZ$J$%BApcrrf+UzW+}}du~sA zZ0bHzc5iZ{y0x?4Jb!z$V78mZ3&r*99S&jhC#0!zrf(~2J}<@fKxfO};$zy_&-zN; z=DMP~$E%~-_5-!PjdRQo{+8|gVWi6L%3f96gh%JMRsB8et6>Mc8uwYe`}Z9~&HV?T zjm)X_hvxA1f~1&UlB%l8mZyKIJnLDjZzq-uz2H&Q zv3{d=bz^(}*7f1C%d_VnZjrUKxIwO|%^w46?Vek*r$N+~_5FRvlnspAlv!rCZ1>8L zN48n-#(Jc0cz>ny!EtpCCGVW?^rda0)Yo-wkBQrE*1ENM-Qk2y1yLqv{oEo}OW6XyhOg(rz z^S9+Qk82x#usqN!=0c|$Wfxw%FKFWyZJ&0?Zt**9Nkf&Uq@gJ+z8Va-|C||uw*gnQ zk{C?TrNxU#ToX*yW-@IhBLlP?R$haF+FWa?F%GRl!l0N?u7xl-W7pGmtIpMV>r=2U z^n|o|>*n`gT+#R&Wl>4%sqrYSTx9$4N@Q8}B8SfjW5)9*OsDb^2{(Pn*zXJa?HF@3 zZPl&$zUwD9N;?;9J=fvH8K1S<;_RLsR)@d)%KK8`+^)X+ugq!fSbEku|5ZU$_hqi_ zZcVal)$jh=!<(MY4Va#^;zr2%=VNXxyjdgt*X*Gyc0Fr2^|oY5)%&{VjRT6#{}T6o zyMP7DEv7y2d-3kcYss;Z?I#w5$u}H+are&EqEQXc4Y_Y`cI%h#CtvvL@%&M$WAn2M zT3vm2BzN?~M{|N!{n5PlunW!B-7bA?`VDuh%gWo;yT93fu-bLcuiOgzy}z~cMZHJK zDNc7&?6%k~*c;oxcfX|O!q8ToFAt2B4EUjT%&Hfid+nM&|Lr7~(wAJ4%PW(|jos@y zTJ$)7J^EpvvXc5=Yf7Yb4LxA0Es<6M$cE9}g#Xwa|LIi+BZ}*-aWK?crZrk9k$~Rx z6lJ2dq9p;1r`E@#sn*AL`_`;#R_W93i)Z-n-4kO>E3lgqt$6=7 z^ltA{QI+=(-I#Q2M#IVW>0i`8{&ef%7iE8@y|ow|*Eu|+UiOLAin7tBQ`+zN@s*~y zS!r6ys5e<@$K&n&b6ol?_m96(GQ3~C!dfw-!_r5t4e{Bw;9lLkjUHX?`)5+SDU$lm zBg)RapLEeNcB-WLt%twg3*7Q;t*u$TUaXmQqSc38WAa9;+$Yo=IBbvg+gpFs=F0kA zoN)GnyJw}h3uZ4~uxPyL$uAZ=t6lePA5wj2%1 z#cY}L+2??uKHTA0i zAK7))WWN;_ub6RH)6BD(k#U!K|A!iPPfZ)>eS6e5-tSXi1rPaZbi|QK*~8XFe_hw< zi{^Js7Fw+uJafZwo$AfmxpiagH#fgj3`|jIqJN@uPw_!(< zj;!tE=CQtO<1kOfnD?o*cD4?DbJ=$O$lXH*jvAV?e&F1=+hY?u1|Q$@Q;Tu=Q}a`5 z&D+w`v`@&WXRS_|9k%d2w&7k`M8T;MqpwR^)qcBnhVp3d+223-eQD2GQ=T1c8`fX9 z_VSI~L1$uvXYRP3;*vjm)gDW&{Y0Eyecz!^l-1$=No`a&76)H^-bB`-+OB>k_VaEJ z^W44s%kfFg>mN!u`|!Y}o%P#sL|m1$XUp;C=4 z4f{42=vjB}rEh2E9g(zLU1DoryJ$?65!+`)sMl4kKPq(X@u5Lg0z7A&D2{Pxa(3$D zly9!<4*D)W_SVC>uj9RSH8gLUY*)C=7%?@-B`W6FjCZ9Mi!W@^91d9jq}}%$f*pJJ z8Q7@%!n1!oe)_sy$IWqHtsCceZ{@c6lb(L)?{D>O>wA{>r@b9tw7uX)o#h3+He}R% z)nm`lEvK3vD!e+}v9IbE-*u-Rc<&BU+^gZ8dCRw@iER1V<@IbQ-X6HvZevi-0By-H z7e=i4c3sW9XV0C6cDC_paCfuUhygFUtz7eZ%z#6)PA}-0IB?gveM77CpZsU#r;mU3 z(r&w$^LkU>!O?U3@17O(WAcXcAC6C%ly~#@+oMh&tZ}iy_r0cPg=Tf{o!aPfWQUh` z4-bBxUgednnw8DSmEm)Cuk3cI?+?!gsGoLTG3W5TQ@?wL_~yN?eLuQQ|7y+Ctnc+~ zGvR5S0?mfU%bFeW8ozQ@kGgHQwMbc_h%J48p=GGun@ZOnm}d-+IR0o@>#IL2?~be0 z-f!>a-zW6?L$=Q;GxK(oS8__ukm|p6d0u;ePMbBF62%})1M#Bm#B$PUX8Zn#^B0f) zx3GTLw|Umz(7^gXZy+~J0$SKvnt5ovn)6l`Z|2o%$on6kq)Mb8Z#t0DrUTpwN@MPu zN3V0N9o<%6$Xr=s-O2O2$6LDBTIgS+QQEzp5i7TuHmfcV{chO4O3s&j(tfbLVE(At z-r1(>4mSTuQd#SNW{gE);+J1c>svQ{?SjyG_xklYePwRs233=NYk&T_@tQ$qYtPT< zaky`FlY7Yn?|O8pZ|i>N8)d|aje%QxU)b*^%loF^lOq{VTEvvuKMnrwYO};unTcKn z%SschT+g(f`trtQg~d-Xg-b&l-m%zKYL~xjn(xCmHyZb}uGy)p%c4O!S8ZEt4efK` z!GnOw!+##UVeqILKet{#uJ_$B;UlU)E_3g3b5cv!HBGx8*xLHN$C-^X-}M{TPHFbV z>G?%Xo`rRtT+6H8zUG;U!y><%XSKRooe@W#ekU6>{zdGglU;U?oA%|7?`!4Oi*<0> za)= zx&Kt>Ms{zj&cXQ`Uvk%Wtdf?*Ui`kw#+^0JMt8W=yv*ueozNW)+X9CK-Q2S;XVBH0 zJ9V$@4xWAB;ai zsJl0@>)m(yoYvt@NBpvGbk)lX!k*4pwmyEXnC!Y}A~a#5ACsN`=M+$Wn}|5m{YCz{ zn&O32d9}QFrlxqBrg*a63g;%%6c5+55sQ;b?3?~oaWr`+W+mvbGbI(rED95{b#DD~ zGc;}W8Avsr&K_zfqiw&jY1+O2Ip$o= zeI5?iA02Q#-fO|8(B`TiRC|9|z2?@2pD$J!-8raxGmilcst;TLw86{EO$hM1ZeH|T zYRk26H4o$+CtSIbmys~p_tgBZVd1-ry45Z#u<@uh=%Jr#eVaEcjxOoFr)>1xZUef8 zwF~;*|Iplly;Mc*(%uy=+_N(yqyM2UIy;L&5y!M8_PsPE_T8B2VETW0;^Hj`pU?n} z6wA`$J=m$J63tK5%hlea!k$MtIlL}@)6e!se6OARF3;7h znXU6p^B-Z~`o)|||0c86q1PklT(=&h**3)HtEhry8@IOl^?1#fX5pIW=dSgc6L_Lw zpf)ghv$@+3r)SMve%OCrW@xX-TDb?>WKG>NqQ(v%&oPBn7mc}}V&1()kmh-t0kzVi zJ)VXaggSfL_t4#xW_vVzwfTozc`v&iT;6T^A+xHxBBJZ3^zVGbEd49H3n`}Z=#1v! zQ@4117#vZjmUW}p_mZ0{-j~dDvnue?PW`3VpVQ8&_MKZ(xO?EZk?+3kYt_dtJABK2 zxAwaywH=$DLXk6FEOj3(YQVB()n>xaImaoxVG#O}1F#O}CWBa_KsuCUt$*mwFK zB6EcuR!HoYH{<=TKogseyOP{}0N=u+O+Ay-#_ zH*V(oj?#pZ27eUPj2+j;Vc6~9D9Js4Sd|3{rR)#P4(SIaTIT334W<=4Ncwj7ydwpd%By;gRz z)HfwO{7k3Q)vnHSZ5fifPmvI}>#X0hT~)5Ed3W~pqF);~aq;OeuKIDmcKvOK*`A7g z^+UISwl9v>o-?_MBK%&5f`QLRzdiEHt%og~wybMVHMr5HOU?_9G+(~8Z{G9U?Rt&6 z(R0hn{M?pXEhnt6)XA^b>QUeN%}yJui2BvOR;o|v0&Q~FZ^HA7zS=qPQ2K(fZ9nW@ zF!`|0j)TpLH(%Kt(eU*jm+bbaBGYbfNqq8r_nyZAm7R-E>4y+*peJbd4))r+fZ z&TG_9r|ngJx3ou-`Q24*<7-`<7(P0e%CU7F*ojI`v)^O z{}MfQRQ-1L%bO3K_NU7A$j@yWww;*w_Sej-4e!DQr2?16o^;`R>Q+B&&$uSZoP8_2aa{c2R7 z?sVMDZo-f_O^@}OK&wCdjvf&eQ0aW9ZOxP${Vz>jbxx=0R=;F%kj2U0o`n=2+g-P> zNB6$LkGqGA@)+Tq8<#RUwm542iK!i@?AgDp_o+C$OqU<3zZzAv{Yu>1;5`kT>ZaJ{ zRIfF5ZHL4$5%KGLzss-b`>0#qs-0u~JGJe6%4(iz>y%;7lE0VD2>jyV$qw%_Z_PQp ze#PTKja1r4zl51i-ZEP0b+^EA-M!hzTHSFE{BHTvUlVsOk?c{MO)WU~cE|UJ0(U1uiZ)HRJXyYuK%Ti{z=yK-=d)Z^t|hliFX&p#P>VpJ8e?0^T+2n?EgPydU^#~ zV0zxJ9!>wdnBHgdhGJgI6m!}OSv*}+JVjGHv7ByRtnt;W))IT|XLa+44xzka9uN`f zj=NUk^3rqvfo4vh`ZZ|gbX58uY37RCqdQw%|KaMaHpK&EzVjEC)ymrV`?90Yw7X82 zT>tw0>uwpauVnMwduXa30i|VFq+_@ys_RY7EisJ&;-`4-Ri^x+0q#kdoRm_Ck;L4cPa5~3fBdjZ2iluYu7ADx{c7z8B+MUND`Vfh#fw_K9yWAF|49YQ zGEQHc_sZ#QvkTLn{;*UvW7LwJ3#zY?`w!o?xoB?fX6nuLZYAD-@pShW2|emr4RUMV zZQ!B-D^15*jj{hOZn@2oITtKL<`f+`d2IQ~heL-yy4G@l*_Gb8vuZ2jepwgcoVD}M zYuuGPTE&v7EnXyr6x@BeqTM$yF6Vp^mzI_Pb@7qqW~-WSzyHIL3niO!jyXNuHd5kT z^rps`Mp4Z-^!nwXMfB`JU+P*aZ_jf5ZT!`yZnh1deeWLCpw^3n|IgO=-O|{xapmo4 zo0dB*I(c5w(f2{yPpw&t1=9>J?=CU&zMowEb!L~o^l`=Ykz3c@aj}^mP^T6M^Tb7AZLAhxRos3=B-ofO{q30+vt#gK}W$1zD;C?AQXQ`1OHpN#He;U;}_d{XjPGKv*WG z9ZbMA;J{8QkS%EoQIM>)3#7mdNjsAva3&nS)(6~EUchC*0n)}S_Bdf7jLp7K0nN$a zeH@}bEEU%;hWnZGUOTy6?fc98BuW1>p|4&q(OJTwFeh!5?fJmFwcl*g!^8Jy?fNWp zdd-@AVI$l1dUtYC?EP>5kdtx$ZIC=;QtJ<a?>{V<%Mrr+56q~ev8!HKCi&9 zoA)id;o#85de8mL)Q!PvzJ0$J?q<;ZwDNlXr!_u1w>Qgv(1yUjZ}{jV-? zJABNeB-0rYnbTu#e_JS5 zKUsuHH}!^*?*3eR%kb}g0@q*4v$R&c)QEm{vZe3v7Y%Jz)>;2oZ``*;^$*7kGyNWs z^((*EoZ_7|X`ig@EyE^eUSJQI6P#x!4{RF?JeG#7gN{6w*2L&#AO#;@0WJdLMHxUb zKpz}CviQwyNmje(hZpb8*mvgR9lsMN*k?uNz75mny8PrG*Ls7-Uq}Wp=^Hk_GH85m z(D=llaW8OaO4Ze}mpm-}mS+H%F%4B8E@LTsHMy-S9U2sU~uc0Ct@~3y|18-rJfR zt+7AOn`hQRftd{F=kv7&{S=s5lixQt`e1K`UbVe%cv2C)}JJnBY`<>F6afwsE`0Ij<_4!(Lw#wm= z^C$niq}Vd&jAL*CtEwf(ogLCy-38lo`G4%=_dUBdG`-}T+HRwXTevp-Tvjd}JS$LA zi))>x(!s{Pyp5l>3Qphf%EoK|#>}U$c??Q=ryIPMthjsmY#4vbuC@IY{wCLh>XWUT z1g;D3h!o#cz&s&*^DC)|-0wwyy-qfYEL?1po~P3MvQwv{JuAN%@N;)v+ IXGb{$00BiQzyJUM literal 0 HcmV?d00001 diff --git a/src/ZString.Unity/Assets/Plugins/System.Memory.dll.meta b/src/ZString.Unity/Assets/Plugins/System.Memory.dll.meta new file mode 100644 index 00000000..eae7a542 --- /dev/null +++ b/src/ZString.Unity/Assets/Plugins/System.Memory.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 093c0580b60756443bc1d9c561452e36 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll b/src/ZString.Unity/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000000000000000000000000000000000000..c66b445c4f964506d6e737a0ce1b898e7cf36841 GIT binary patch literal 16968 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 Path.GetExtension(x) == ".cs" || Path.GetExtension(x) == ".meta" || Path.GetExtension(x) == ".asmdef") + .Where(x => Path.GetFileNameWithoutExtension(x) != "_InternalVisibleTo") + .Select(x => "Assets" + x.Replace(Application.dataPath, "").Replace(@"\", "/")) + .ToArray(); + + var netStandardsAsset = Directory.EnumerateFiles(Path.Combine(Application.dataPath, "Plugins/"), "*", SearchOption.AllDirectories) + .Select(x => "Assets" + x.Replace(Application.dataPath, "").Replace(@"\", "/")) + .ToArray(); + + assets = assets.Concat(netStandardsAsset).ToArray(); + + UnityEngine.Debug.Log("Export below files" + Environment.NewLine + string.Join(Environment.NewLine, assets)); + + var dir = new FileInfo(exportPath).Directory; + if (!dir.Exists) dir.Create(); + AssetDatabase.ExportPackage( + assets, + exportPath, + ExportPackageOptions.Default); + + UnityEngine.Debug.Log("Export complete: " + Path.GetFullPath(exportPath)); + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs.meta b/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs.meta new file mode 100644 index 00000000..63bc3894 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0104ef67be3b9ca498ff698ad4e0bd71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString.meta b/src/ZString.Unity/Assets/Scripts/ZString.meta new file mode 100644 index 00000000..bf831bf7 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1260d4de3d15f5a45a5ef60c7fd826f0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs b/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs new file mode 100644 index 00000000..2548474a --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs @@ -0,0 +1,48 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + internal static class EnumUtil + { + static readonly Dictionary names; + static readonly Dictionary utf8names; + + static EnumUtil() + { + var enumNames = Enum.GetNames(typeof(T)); + var values = Enum.GetValues(typeof(T)); + names = new Dictionary(enumNames.Length); + utf8names = new Dictionary(enumNames.Length); + for (int i = 0; i < enumNames.Length; i++) + { + names.Add((T)values.GetValue(i), enumNames[i]); + utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i])); + } + } + + public static bool TryFormatUtf16(T value, Span dest, out int written, ReadOnlySpan _) + { + if (!names.TryGetValue(value, out var v)) + { + v = value.ToString(); + } + + written = v.Length; + return v.AsSpan().TryCopyTo(dest); + } + + public static bool TryFormatUtf8(T value, Span dest, out int written, StandardFormat _) + { + if (!utf8names.TryGetValue(value, out var v)) + { + v = Encoding.UTF8.GetBytes(value.ToString()); + } + + written = v.Length; + return v.AsSpan().TryCopyTo(dest); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs.meta new file mode 100644 index 00000000..f545c639 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d12377b4cfb6e604592941b9cdfbcc92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs b/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs new file mode 100644 index 00000000..9808ef47 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs @@ -0,0 +1,55 @@ +using System; + +namespace Cysharp.Text +{ + internal static class FormatParser + { + // {index[,alignment][:formatString]} + + public readonly ref struct ParseResult + { + public readonly int Index; + public readonly ReadOnlySpan FormatString; + public readonly int LastIndex; + + public ParseResult(int index, ReadOnlySpan formatString, int lastIndex) + { + Index = index; + FormatString = formatString; + LastIndex = lastIndex; + } + } + + public static ParseResult Parse(ReadOnlySpan format) + { + int index = -1; + var formatStart = -1; + + // ignore start '{' + for (int i = 1; i < format.Length; i++) + { + if (format[i] == '}') + { + if (index == -1) + { + index = Int32.Parse(format.Slice(1, i - 1)); + return new ParseResult(index, default, i); + } + else + { + var formatString = format.Slice(formatStart, i - formatStart); + return new ParseResult(index, formatString, i); + } + } + + if (index == -1 && format[i] == ',' || format[i] == ':') + { + index = Int32.Parse(format.Slice(1, i - 1)); + formatStart = i + 1; + } + } + + throw new FormatException("Invalid format string. format:" + format.ToString()); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs.meta new file mode 100644 index 00000000..ca880114 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3676d0a8288bd1469a9162fec83cf5a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims.meta new file mode 100644 index 00000000..57bbf8df --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ff030f3dccf88234594d248d9d3c845d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion.meta new file mode 100644 index 00000000..296bad38 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2fc8643811380444d807e850929557c0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs new file mode 100644 index 00000000..b10835bf --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text.Internal +{ + // https://github.com/google/double-conversion/blob/master/double-conversion/diy-fp.cc + // https://github.com/google/double-conversion/blob/master/double-conversion/diy-fp.h + + internal struct DiyFp + { + public const int kSignificandSize = 64; + public const ulong kUint64MSB = 0x8000000000000000; // 0x80000000_00000000; + + // uint64_t f_; + // int e_; + // long f() const { return f_; } + // int e() const { return e_; } + // void set_f(long new_value) { f_ = new_value; } + // void set_e(int new_value) { e_ = new_value; } + + // public field, not safe... + public ulong f; + public int e; + + public DiyFp(ulong significand, int exponent) + { + this.f = significand; + this.e = exponent; + } + + // this = this - other. + // The exponents of both numbers must be the same and the significand of this + // must be bigger than the significand of other. + // The result will not be normalized. + public void Subtract(ref DiyFp other) + { + f -= other.f; + } + + // Returns a - b. + // The exponents of both numbers must be the same and this must be bigger + // than other. The result will not be normalized. + public static DiyFp Minus(ref DiyFp a, ref DiyFp b) + { + DiyFp result = a; + result.Subtract(ref b); + return result; + } + + public static DiyFp operator -(DiyFp lhs, DiyFp rhs) + { + return Minus(ref lhs, ref rhs); + } + + // this = this * other. + public void Multiply(ref DiyFp other) + { + // Simply "emulates" a 128 bit multiplication. + // However: the resulting number only contains 64 bits. The least + // significant 64 bits are only used for rounding the most significant 64 + // bits. + const long kM32 = 0xFFFFFFFFU; + ulong a = f >> 32; + ulong b = f & kM32; + ulong c = other.f >> 32; + ulong d = other.f & kM32; + ulong ac = a * c; + ulong bc = b * c; + ulong ad = a * d; + ulong bd = b * d; + ulong tmp = (bd >> 32) + (ad & kM32) + (bc & kM32); + // By adding 1U << 31 to tmp we round the final result. + // Halfway cases will be round up. + tmp += 1U << 31; + ulong result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); + e += other.e + 64; + f = result_f; + } + + // returns a * b; + public static DiyFp Times(ref DiyFp a, ref DiyFp b) + { + DiyFp result = a; + result.Multiply(ref b); + return result; + } + + public static DiyFp operator *(DiyFp lhs, DiyFp rhs) + { + return Times(ref lhs, ref rhs); + } + + public void Normalize() + { + ulong significand = f; + int exponent = e; + + // This method is mainly called for normalizing boundaries. In general + // boundaries need to be shifted by 10 bits. We thus optimize for this case. + const ulong k10MSBits = 0xFFC0000000000000; // UINT64_2PART_C(0xFFC00000, 00000000); + while ((significand & k10MSBits) == 0) + { + significand <<= 10; + exponent -= 10; + } + while ((significand & kUint64MSB) == 0) + { + significand <<= 1; + exponent--; + } + f = significand; + e = exponent; + } + + public static DiyFp Normalize(ref DiyFp a) + { + DiyFp result = a; + result.Normalize(); + return result; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs.meta new file mode 100644 index 00000000..1c5cedb0 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88e6d984bcc8a9f449710f9765acf485 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs new file mode 100644 index 00000000..589b966f --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs @@ -0,0 +1,890 @@ +using System; +using System.Globalization; + +namespace Cysharp.Text.Internal +{ + using uint64_t = System.UInt64; + using uint32_t = System.UInt32; + using System.Collections.Generic; + using System.Text; + + internal ref struct StringBuilder + { + public Span buffer; + public int offset; + + public StringBuilder(Span buffer) + { + this.buffer = buffer; + this.offset = 0; + } + + public bool TryAddCharacter(char str) + { + if (buffer.Length - offset < 1) return false; + buffer[offset++] = str; + return true; + } + + public bool TryAddCharacter(byte str) + { + if (buffer.Length - offset < 1) return false; + buffer[offset++] = (char)str; + return true; + } + + public bool TryAddString(char[] str) + { + if (buffer.Length - offset < str.Length) return false; + for (int i = 0; i < str.Length; i++) + { + buffer[offset + i] = str[i]; + } + offset += str.Length; + return true; + } + + public bool TryAddSubstring(char[] str, int length) + { + if (buffer.Length - offset < length) return false; + for (int i = 0; i < length; i++) + { + buffer[offset + i] = str[i]; + } + offset += length; + return true; + } + + public bool TryAddSubstring(byte[] str, int length) + { + if (buffer.Length - offset < length) return false; + for (int i = 0; i < length; i++) + { + buffer[offset + i] = (char)str[i]; + } + offset += length; + return true; + } + + public bool TryAddSubstring(char[] str, int start, int length) + { + if (buffer.Length - offset < (length - start)) return false; + for (int i = 0; i < length; i++) + { + buffer[offset + i] = str[start + i]; + } + offset += length; + return true; + } + + public bool TryAddSubstring(byte[] str, int start, int length) + { + if (buffer.Length - offset < (length - start)) return false; + for (int i = 0; i < length; i++) + { + buffer[offset + i] = (char)str[start + i]; + } + offset += length; + return true; + } + + public bool TryAddPadding(char c, int count) + { + if (buffer.Length - offset < count) return false; + for (int i = 0; i < count; i++) + { + buffer[offset + i] = c; + } + offset += count; + return true; + } + + public bool TryAddStringSlow(string str) + { + var s = str.AsSpan(); + if (s.TryCopyTo(buffer.Slice(offset))) + { + offset += s.Length; + return true; + } + return false; + } + } + + // C# API + internal static partial class DoubleToStringConverter + { + public static bool TryFormat(Span destination, float value, out int charsWritten) + { + var sb = new StringBuilder(destination); + if (!ToShortestIeeeNumber(value, ref sb, DtoaMode.SHORTEST_SINGLE)) + { + charsWritten = 0; + return false; + } + + charsWritten = sb.offset; + return true; + } + + public static bool TryFormat(Span destination, double value, out int charsWritten) + { + var sb = new StringBuilder(destination); + if (!ToShortestIeeeNumber(value, ref sb, DtoaMode.SHORTEST)) + { + charsWritten = 0; + return false; + } + + charsWritten = sb.offset; + return true; + } + + [ThreadStatic] + static byte[] exponentialRepBuffer; + + [ThreadStatic] + static byte[] decimalRepBuffer; + + static byte[] GetDecimalRepBuffer(int size) + { + if (decimalRepBuffer == null) + { + decimalRepBuffer = new byte[size]; + } + return decimalRepBuffer; + } + + static byte[] GetExponentialRepBuffer(int size) + { + if (exponentialRepBuffer == null) + { + exponentialRepBuffer = new byte[size]; + } + return exponentialRepBuffer; + } + } + + // private porting methods + // https://github.com/google/double-conversion/blob/master/double-conversion/fast-dtoa.h + // https://github.com/google/double-conversion/blob/master/double-conversion/fast-dtoa.cc + + internal static partial class DoubleToStringConverter + { + enum FastDtoaMode + { + // Computes the shortest representation of the given input. The returned + // result will be the most accurate number of this length. Longer + // representations might be more accurate. + FAST_DTOA_SHORTEST, + // Same as FAST_DTOA_SHORTEST but for single-precision floats. + FAST_DTOA_SHORTEST_SINGLE, + // Computes a representation where the precision (number of digits) is + // given as input. The precision is independent of the decimal point. + // FAST_DTOA_PRECISION + }; + + enum DtoaMode + { + SHORTEST, + SHORTEST_SINGLE, + // FIXED, + // PRECISION + } + + enum Flags + { + NO_FLAGS = 0, + EMIT_POSITIVE_EXPONENT_SIGN = 1, + EMIT_TRAILING_DECIMAL_POINT = 2, + EMIT_TRAILING_ZERO_AFTER_POINT = 4, + UNIQUE_ZERO = 8 + }; + + // C# constants + static readonly char[] infinity_symbol_ = double.PositiveInfinity.ToString().ToCharArray(); + static readonly char[] nan_symbol_ = double.NaN.ToString().ToCharArray(); + + // constructor parameter, same as EcmaScriptConverter + //DoubleToStringConverter(int flags, + // const char* infinity_symbol, + // const char* nan_symbol, + // char exponent_character, + // int decimal_in_shortest_low, + // int decimal_in_shortest_high, + // int max_leading_padding_zeroes_in_precision_mode, + // int max_trailing_padding_zeroes_in_precision_mode) + + //const char exponent_character_; + //const int decimal_in_shortest_low_; + //const int decimal_in_shortest_high_; + //const int max_leading_padding_zeroes_in_precision_mode_; + //const int max_trailing_padding_zeroes_in_precision_mode_; + + static readonly Flags flags_ = Flags.UNIQUE_ZERO | Flags.EMIT_POSITIVE_EXPONENT_SIGN; + static readonly char exponent_character_ = 'E'; + static readonly int decimal_in_shortest_low_ = -4; // C# ToString("G") + static readonly int decimal_in_shortest_high_ = 15;// C# ToString("G") + + const int kBase10MaximalLength = 17; + + const int kFastDtoaMaximalLength = 17; + // Same for single-precision numbers. + const int kFastDtoaMaximalSingleLength = 9; + + // The minimal and maximal target exponent define the range of w's binary + // exponent, where 'w' is the result of multiplying the input by a cached power + // of ten. + // + // A different range might be chosen on a different platform, to optimize digit + // generation, but a smaller range requires more powers of ten to be cached. + const int kMinimalTargetExponent = -60; + const int kMaximalTargetExponent = -32; + + // Adjusts the last digit of the generated number, and screens out generated + // solutions that may be inaccurate. A solution may be inaccurate if it is + // outside the safe interval, or if we cannot prove that it is closer to the + // input than a neighboring representation of the same length. + // + // Input: * buffer containing the digits of too_high / 10^kappa + // * the buffer's length + // * distance_too_high_w == (too_high - w).f() * unit + // * unsafe_interval == (too_high - too_low).f() * unit + // * rest = (too_high - buffer * 10^kappa).f() * unit + // * ten_kappa = 10^kappa * unit + // * unit = the common multiplier + // Output: returns true if the buffer is guaranteed to contain the closest + // representable number to the input. + // Modifies the generated digits in the buffer to approach (round towards) w. + static bool RoundWeed(byte[] buffer, + int length, + uint64_t distance_too_high_w, + uint64_t unsafe_interval, + uint64_t rest, + uint64_t ten_kappa, + uint64_t unit) + { + uint64_t small_distance = distance_too_high_w - unit; + uint64_t big_distance = distance_too_high_w + unit; + // Let w_low = too_high - big_distance, and + // w_high = too_high - small_distance. + // Note: w_low < w < w_high + // + // The real w (* unit) must lie somewhere inside the interval + // ]w_low; w_high[ (often written as "(w_low; w_high)") + + // Basically the buffer currently contains a number in the unsafe interval + // ]too_low; too_high[ with too_low < w < too_high + // + // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ^v 1 unit ^ ^ ^ ^ + // boundary_high --------------------- . . . . + // ^v 1 unit . . . . + // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . + // . . ^ . . + // . big_distance . . . + // . . . . rest + // small_distance . . . . + // v . . . . + // w_high - - - - - - - - - - - - - - - - - - . . . . + // ^v 1 unit . . . . + // w ---------------------------------------- . . . . + // ^v 1 unit v . . . + // w_low - - - - - - - - - - - - - - - - - - - - - . . . + // . . v + // buffer --------------------------------------------------+-------+-------- + // . . + // safe_interval . + // v . + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . + // ^v 1 unit . + // boundary_low ------------------------- unsafe_interval + // ^v 1 unit v + // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // + // Note that the value of buffer could lie anywhere inside the range too_low + // to too_high. + // + // boundary_low, boundary_high and w are approximations of the real boundaries + // and v (the input number). They are guaranteed to be precise up to one unit. + // In fact the error is guaranteed to be strictly less than one unit. + // + // Anything that lies outside the unsafe interval is guaranteed not to round + // to v when read again. + // Anything that lies inside the safe interval is guaranteed to round to v + // when read again. + // If the number inside the buffer lies inside the unsafe interval but not + // inside the safe interval then we simply do not know and bail out (returning + // false). + // + // Similarly we have to take into account the imprecision of 'w' when finding + // the closest representation of 'w'. If we have two potential + // representations, and one is closer to both w_low and w_high, then we know + // it is closer to the actual value v. + // + // By generating the digits of too_high we got the largest (closest to + // too_high) buffer that is still in the unsafe interval. In the case where + // w_high < buffer < too_high we try to decrement the buffer. + // This way the buffer approaches (rounds towards) w. + // There are 3 conditions that stop the decrementation process: + // 1) the buffer is already below w_high + // 2) decrementing the buffer would make it leave the unsafe interval + // 3) decrementing the buffer would yield a number below w_high and farther + // away than the current number. In other words: + // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high + // Instead of using the buffer directly we use its distance to too_high. + // Conceptually rest ~= too_high - buffer + // We need to do the following tests in this order to avoid over- and + // underflows. + while (rest < small_distance && // Negated condition 1 + unsafe_interval - rest >= ten_kappa && // Negated condition 2 + (rest + ten_kappa < small_distance || // buffer{-1} > w_high + small_distance - rest >= rest + ten_kappa - small_distance)) + { + buffer[length - 1]--; + rest += ten_kappa; + } + + // We have approached w+ as much as possible. We now test if approaching w- + // would require changing the buffer. If yes, then we have two possible + // representations close to w, but we cannot decide which one is closer. + if (rest < big_distance && + unsafe_interval - rest >= ten_kappa && + (rest + ten_kappa < big_distance || + big_distance - rest > rest + ten_kappa - big_distance)) + { + return false; + } + + // Weeding test. + // The safe interval is [too_low + 2 ulp; too_high - 2 ulp] + // Since too_low = too_high - unsafe_interval this is equivalent to + // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp] + // Conceptually we have: rest ~= too_high - buffer + return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit); + } + + // Returns the biggest power of ten that is less than or equal to the given + // number. We furthermore receive the maximum number of bits 'number' has. + // + // Returns power == 10^(exponent_plus_one-1) such that + // power <= number < power * 10. + // If number_bits == 0 then 0^(0-1) is returned. + // The number of bits must be <= 32. + // Precondition: number < (1 << (number_bits + 1)). + + // Inspired by the method for finding an integer log base 10 from here: + // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 + static readonly uint[] kSmallPowersOfTen = new uint[] { 0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + + static void BiggestPowerTen(uint32_t number, + int number_bits, + out uint32_t power, + out int exponent_plus_one) + { + // 1233/4096 is approximately 1/lg(10). + int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12); + // We increment to skip over the first entry in the kPowersOf10 table. + // Note: kPowersOf10[i] == 10^(i-1). + exponent_plus_one_guess++; + // We don't have any guarantees that 2^number_bits <= number. + if (number < kSmallPowersOfTen[exponent_plus_one_guess]) + { + exponent_plus_one_guess--; + } + power = kSmallPowersOfTen[exponent_plus_one_guess]; + exponent_plus_one = exponent_plus_one_guess; + } + + // Generates the digits of input number w. + // w is a floating-point number (DiyFp), consisting of a significand and an + // exponent. Its exponent is bounded by kMinimalTargetExponent and + // kMaximalTargetExponent. + // Hence -60 <= w.e() <= -32. + // + // Returns false if it fails, in which case the generated digits in the buffer + // should not be used. + // Preconditions: + // * low, w and high are correct up to 1 ulp (unit in the last place). That + // is, their error must be less than a unit of their last digits. + // * low.e() == w.e() == high.e() + // * low < w < high, and taking into account their error: low~ <= high~ + // * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent + // Postconditions: returns false if procedure fails. + // otherwise: + // * buffer is not null-terminated, but len contains the number of digits. + // * buffer contains the shortest possible decimal digit-sequence + // such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the + // correct values of low and high (without their error). + // * if more than one decimal representation gives the minimal number of + // decimal digits then the one closest to W (where W is the correct value + // of w) is chosen. + // Remark: this procedure takes into account the imprecision of its input + // numbers. If the precision is not enough to guarantee all the postconditions + // then false is returned. This usually happens rarely (~0.5%). + // + // Say, for the sake of example, that + // w.e() == -48, and w.f() == 0x1234567890abcdef + // w's value can be computed by w.f() * 2^w.e() + // We can obtain w's integral digits by simply shifting w.f() by -w.e(). + // -> w's integral part is 0x1234 + // w's fractional part is therefore 0x567890abcdef. + // Printing w's integral part is easy (simply print 0x1234 in decimal). + // In order to print its fraction we repeatedly multiply the fraction by 10 and + // get each digit. Example the first digit after the point would be computed by + // (0x567890abcdef * 10) >> 48. -> 3 + // The whole thing becomes slightly more complicated because we want to stop + // once we have enough digits. That is, once the digits inside the buffer + // represent 'w' we can stop. Everything inside the interval low - high + // represents w. However we have to pay attention to low, high and w's + // imprecision. + static bool DigitGen(DiyFp low, + DiyFp w, + DiyFp high, + byte[] buffer, + out int length, + out int kappa) + { + // low, w and high are imprecise, but by less than one ulp (unit in the last + // place). + // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that + // the new numbers are outside of the interval we want the final + // representation to lie in. + // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield + // numbers that are certain to lie in the interval. We will use this fact + // later on. + // We will now start by generating the digits within the uncertain + // interval. Later we will weed out representations that lie outside the safe + // interval and thus _might_ lie outside the correct interval. + uint64_t unit = 1; + DiyFp too_low = new DiyFp(low.f - unit, low.e); + DiyFp too_high = new DiyFp(high.f + unit, high.e); + // too_low and too_high are guaranteed to lie outside the interval we want the + // generated number in. + DiyFp unsafe_interval = DiyFp.Minus(ref too_high, ref too_low); + // We now cut the input number into two parts: the integral digits and the + // fractionals. We will not write any decimal separator though, but adapt + // kappa instead. + // Reminder: we are currently computing the digits (stored inside the buffer) + // such that: too_low < buffer * 10^kappa < too_high + // We use too_high for the digit_generation and stop as soon as possible. + // If we stop early we effectively round down. + DiyFp one = new DiyFp((uint64_t)(1) << -w.e, w.e); + // Division by one is a shift. + uint32_t integrals = (uint32_t)(too_high.f >> -one.e); + // Modulo by one is an and. + uint64_t fractionals = too_high.f & (one.f - 1); + uint32_t divisor; + int divisor_exponent_plus_one; + BiggestPowerTen(integrals, DiyFp.kSignificandSize - (-one.e), + out divisor, out divisor_exponent_plus_one); + kappa = divisor_exponent_plus_one; + length = 0; + // Loop invariant: buffer = too_high / 10^kappa (integer division) + // The invariant holds for the first iteration: kappa has been initialized + // with the divisor exponent + 1. And the divisor is the biggest power of ten + // that is smaller than integrals. + while (kappa > 0) + { + int digit = unchecked((int)(integrals / divisor)); + buffer[length] = (byte)((byte)'0' + digit); + (length)++; + integrals %= divisor; + (kappa)--; + // Note that kappa now equals the exponent of the divisor and that the + // invariant thus holds again. + uint64_t rest = + ((uint64_t)(integrals) << -one.e) + fractionals; + // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e()) + // Reminder: unsafe_interval.e() == one.e() + if (rest < unsafe_interval.f) + { + // Rounding down (by not emitting the remaining digits) yields a number + // that lies within the unsafe interval. + return RoundWeed(buffer, length, DiyFp.Minus(ref too_high, ref w).f, + unsafe_interval.f, rest, + (uint64_t)(divisor) << -one.e, unit); + } + divisor /= 10; + } + + // The integrals have been generated. We are at the point of the decimal + // separator. In the following loop we simply multiply the remaining digits by + // 10 and divide by one. We just need to pay attention to multiply associated + // data (like the interval or 'unit'), too. + // Note that the multiplication by 10 does not overflow, because w.e >= -60 + // and thus one.e >= -60. + for (; ; ) + { + fractionals *= 10; + unit *= 10; + unsafe_interval.f = (unsafe_interval.f * 10); + // Integer division by one. + int digit = (int)(fractionals >> -one.e); + buffer[length] = (byte)((byte)'0' + digit); + (length)++; + fractionals &= one.f - 1; // Modulo by one. + (kappa)--; + if (fractionals < unsafe_interval.f) + { + return RoundWeed(buffer, length, DiyFp.Minus(ref too_high, ref w).f * unit, + unsafe_interval.f, fractionals, one.f, unit); + } + } + } + + // Provides a decimal representation of v. + // Returns true if it succeeds, otherwise the result cannot be trusted. + // There will be *length digits inside the buffer (not null-terminated). + // If the function returns true then + // v == (double) (buffer * 10^decimal_exponent). + // The digits in the buffer are the shortest representation possible: no + // 0.09999999999999999 instead of 0.1. The shorter representation will even be + // chosen even if the longer one would be closer to v. + // The last digit will be closest to the actual v. That is, even if several + // digits might correctly yield 'v' when read again, the closest will be + // computed. + static bool Grisu3(double v, + FastDtoaMode mode, + byte[] buffer, + out int length, + out int decimal_exponent) + { + DiyFp w = new Double(v).AsNormalizedDiyFp(); + // boundary_minus and boundary_plus are the boundaries between v and its + // closest floating-point neighbors. Any number strictly between + // boundary_minus and boundary_plus will round to v when convert to a double. + // Grisu3 will never output representations that lie exactly on a boundary. + DiyFp boundary_minus, boundary_plus; + if (mode == FastDtoaMode.FAST_DTOA_SHORTEST) + { + new Double(v).NormalizedBoundaries(out boundary_minus, out boundary_plus); + } + else if (mode == FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE) + { + float single_v = (float)(v); + new Single(single_v).NormalizedBoundaries(out boundary_minus, out boundary_plus); + } + else + { + throw new Exception("Invalid Mode."); + } + + DiyFp ten_mk; // Cached power of ten: 10^-k + int mk; // -k + int ten_mk_minimal_binary_exponent = + kMinimalTargetExponent - (w.e + DiyFp.kSignificandSize); + int ten_mk_maximal_binary_exponent = + kMaximalTargetExponent - (w.e + DiyFp.kSignificandSize); + PowersOfTenCache.GetCachedPowerForBinaryExponentRange( + ten_mk_minimal_binary_exponent, + ten_mk_maximal_binary_exponent, + out ten_mk, out mk); + + // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a + // 64 bit significand and ten_mk is thus only precise up to 64 bits. + + // The DiyFp::Times procedure rounds its result, and ten_mk is approximated + // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now + // off by a small amount. + // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. + // In other words: let f = scaled_w.f() and e = scaled_w.e(), then + // (f-1) * 2^e < w*10^k < (f+1) * 2^e + DiyFp scaled_w = DiyFp.Times(ref w, ref ten_mk); + + // In theory it would be possible to avoid some recomputations by computing + // the difference between w and boundary_minus/plus (a power of 2) and to + // compute scaled_boundary_minus/plus by subtracting/adding from + // scaled_w. However the code becomes much less readable and the speed + // enhancements are not terriffic. + DiyFp scaled_boundary_minus = DiyFp.Times(ref boundary_minus, ref ten_mk); + DiyFp scaled_boundary_plus = DiyFp.Times(ref boundary_plus, ref ten_mk); + + // DigitGen will generate the digits of scaled_w. Therefore we have + // v == (double) (scaled_w * 10^-mk). + // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an + // integer than it will be updated. For instance if scaled_w == 1.23 then + // the buffer will be filled with "123" und the decimal_exponent will be + // decreased by 2. + int kappa; + bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, + buffer, out length, out kappa); + decimal_exponent = -mk + kappa; + return result; + } + + static bool FastDtoa(double v, + FastDtoaMode mode, + // int requested_digits, + byte[] buffer, + out int length, + out int decimal_point) + { + bool result = false; + int decimal_exponent = 0; + switch (mode) + { + case FastDtoaMode.FAST_DTOA_SHORTEST: + case FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE: + result = Grisu3(v, mode, buffer, out length, out decimal_exponent); + break; + // case FastDtoaMode.FAST_DTOA_PRECISION: + //result = Grisu3Counted(v, requested_digits, buffer, length, &decimal_exponent); + default: + throw new Exception("unreachable code."); + } + if (result) + { + decimal_point = length + decimal_exponent; + } + else + { + decimal_point = -1; + } + return result; + } + + // https://github.com/google/double-conversion/blob/master/double-conversion/double-conversion.cc + + static bool HandleSpecialValues( + double value, + ref StringBuilder result_builder) + { + Double double_inspect = new Double(value); + if (double_inspect.IsInfinite()) + { + if (infinity_symbol_ == null) return false; + if (value < 0) + { + if (!result_builder.TryAddCharacter('-')) return false; + } + if (!result_builder.TryAddString(infinity_symbol_)) return false; + return true; + } + if (double_inspect.IsNan()) + { + if (nan_symbol_ == null) return false; + if (!result_builder.TryAddString(nan_symbol_)) return false; + return true; + } + return false; + } + + static bool ToShortestIeeeNumber( + double value, + ref StringBuilder result_builder, + DtoaMode mode) + { + if (new Double(value).IsSpecial()) + { + return HandleSpecialValues(value, ref result_builder); + } + + int decimal_point; + bool sign; + const int kDecimalRepCapacity = kBase10MaximalLength + 1; + var decimal_rep = GetDecimalRepBuffer(kDecimalRepCapacity); // byte[] decimal_rep = new byte[kDecimalRepCapacity]; + int decimal_rep_length; + + var fastworked = DoubleToAscii(value, mode, 0, decimal_rep, + out sign, out decimal_rep_length, out decimal_point); + + if (!fastworked) + { + // C# custom, slow path + var str = value.ToString("G17", CultureInfo.InvariantCulture); + if (!result_builder.TryAddStringSlow(str)) return false; + return true; + } + + bool unique_zero = (flags_ & Flags.UNIQUE_ZERO) != 0; + if (sign && (value != 0.0 || !unique_zero)) + { + if (!result_builder.TryAddCharacter('-')) return false; + } + + int exponent = decimal_point - 1; + if ((decimal_in_shortest_low_ <= exponent) && + (exponent < decimal_in_shortest_high_)) + { + return CreateDecimalRepresentation(decimal_rep, decimal_rep_length, + decimal_point, + Math.Max(0, decimal_rep_length - decimal_point), + ref result_builder); + } + else + { + return CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, + ref result_builder); + } + } + + static bool CreateDecimalRepresentation( + byte[] decimal_digits, + int length, + int decimal_point, + int digits_after_point, + ref StringBuilder result_builder) + { + // Create a representation that is padded with zeros if needed. + if (decimal_point <= 0) + { + // "0.00000decimal_rep" or "0.000decimal_rep00". + if (!result_builder.TryAddCharacter('0')) return false; + if (digits_after_point > 0) + { + if (!result_builder.TryAddCharacter('.')) return false; + if (!result_builder.TryAddPadding('0', -decimal_point)) return false; + if (!result_builder.TryAddSubstring(decimal_digits, length)) return false; + int remaining_digits = digits_after_point - (-decimal_point) - length; + if (!result_builder.TryAddPadding('0', remaining_digits)) return false; + } + } + else if (decimal_point >= length) + { + // "decimal_rep0000.00000" or "decimal_rep.0000". + if (!result_builder.TryAddSubstring(decimal_digits, length)) return false; + if (!result_builder.TryAddPadding('0', decimal_point - length)) return false; + if (digits_after_point > 0) + { + if (!result_builder.TryAddCharacter('.')) return false; + if (!result_builder.TryAddPadding('0', digits_after_point)) return false; + } + } + else + { + // "decima.l_rep000". + if (!result_builder.TryAddSubstring(decimal_digits, decimal_point)) return false; + if (!result_builder.TryAddCharacter('.')) return false; + if (!result_builder.TryAddSubstring(decimal_digits, decimal_point, length - decimal_point)) return false; + int remaining_digits = digits_after_point - (length - decimal_point); + if (!result_builder.TryAddPadding('0', remaining_digits)) return false; + } + if (digits_after_point == 0) + { + if ((flags_ & Flags.EMIT_TRAILING_DECIMAL_POINT) != 0) + { + if (!result_builder.TryAddCharacter('.')) return false; + } + if ((flags_ & Flags.EMIT_TRAILING_ZERO_AFTER_POINT) != 0) + { + if (!result_builder.TryAddCharacter('0')) return false; + } + } + + return true; + } + + static bool CreateExponentialRepresentation( + byte[] decimal_digits, + int length, + int exponent, + ref StringBuilder result_builder) + { + if (!result_builder.TryAddCharacter(decimal_digits[0])) return false; + if (length != 1) + { + if (!result_builder.TryAddCharacter('.')) return false; + if (!result_builder.TryAddSubstring(decimal_digits, 1, length - 1)) return false; + } + if (!result_builder.TryAddCharacter(exponent_character_)) return false; + if (exponent < 0) + { + if (!result_builder.TryAddCharacter('-')) return false; + exponent = -exponent; + } + else + { + if ((flags_ & Flags.EMIT_POSITIVE_EXPONENT_SIGN) != 0) + { + if (!result_builder.TryAddCharacter('+')) return false; + } + } + if (exponent == 0) + { + if (!result_builder.TryAddCharacter('0')) return false; + return true; + } + const int kMaxExponentLength = 5; + byte[] buffer = GetExponentialRepBuffer(kMaxExponentLength + 1); + buffer[kMaxExponentLength] = (byte)'\0'; + int first_char_pos = kMaxExponentLength; + while (exponent > 0) + { + buffer[--first_char_pos] = (byte)((byte)'0' + (exponent % 10)); + exponent /= 10; + } + if (!result_builder.TryAddSubstring(buffer, first_char_pos, kMaxExponentLength - first_char_pos)) return false; + + return true; + } + + // modified, return fast_worked. + static bool DoubleToAscii(double v, + DtoaMode mode, + int requested_digits, + //byte[] buffer, + //int buffer_length, + byte[] vector, // already allocate + out bool sign, + out int length, + out int point) + { + if (new Double(v).Sign() < 0) + { + sign = true; + v = -v; + } + else + { + sign = false; + } + + //if (mode == DtoaMode.PRECISION && requested_digits == 0) + //{ + // vector[0] = '\0'; + // *length = 0; + // return; + //} + + if (v == 0) + { + vector[0] = (byte)'0'; + // vector[1] = '\0'; + length = 1; + point = 1; + return true; + } + + bool fast_worked; + switch (mode) + { + case DtoaMode.SHORTEST: + fast_worked = FastDtoa(v, FastDtoaMode.FAST_DTOA_SHORTEST, vector, out length, out point); + break; + case DtoaMode.SHORTEST_SINGLE: + fast_worked = FastDtoa(v, FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE, vector, out length, out point); + break; + //case FIXED: + // fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); + // break; + //case PRECISION: + // fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, + // vector, length, point); + // break; + default: + fast_worked = false; + throw new Exception("Unreachable code."); + } + // if (fast_worked) return; + + // If the fast dtoa didn't succeed use the slower bignum version. + // BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); + // BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); + // vector[*length] = '\0'; + + return fast_worked; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs.meta new file mode 100644 index 00000000..0ef96f87 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee67482db3b18f24f8e0fd7944941e44 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs new file mode 100644 index 00000000..55bc2fc3 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs @@ -0,0 +1,441 @@ +using System; +using System.Runtime.InteropServices; + +namespace Cysharp.Text.Internal +{ + using uint32_t = UInt32; + + [StructLayout(LayoutKind.Explicit, Pack = 1)] + internal struct UnionDoubleULong + { + [FieldOffset(0)] + public double d; + [FieldOffset(0)] + public ulong u64; + } + + [StructLayout(LayoutKind.Explicit, Pack = 1)] + internal struct UnionFloatUInt + { + [FieldOffset(0)] + public float f; + [FieldOffset(0)] + public uint u32; + } + + // https://github.com/google/double-conversion/blob/master/double-conversion/ieee.h + + internal struct Double + { + public const ulong kSignMask = (0x8000000000000000); + public const ulong kExponentMask = (0x7FF0000000000000); + public const ulong kSignificandMask = (0x000FFFFFFFFFFFFF); + public const ulong kHiddenBit = (0x0010000000000000); + public const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. + public const int kSignificandSize = 53; + + const int kExponentBias = 0x3FF + kPhysicalSignificandSize; + const int kDenormalExponent = -kExponentBias + 1; + const int kMaxExponent = 0x7FF - kExponentBias; + const ulong kInfinity = (0x7FF0000000000000); + const ulong kNaN = (0x7FF8000000000000); + + ulong d64_; + + public Double(double d) + { + d64_ = new UnionDoubleULong { d = d }.u64; + } + + public Double(DiyFp d) + { + d64_ = DiyFpToUint64(d); + } + + // The value encoded by this Double must be greater or equal to +0.0. + // It must not be special (infinity, or NaN). + public DiyFp AsDiyFp() + { + return new DiyFp(Significand(), Exponent()); + } + + // The value encoded by this Double must be strictly greater than 0. + public DiyFp AsNormalizedDiyFp() + { + ulong f = Significand(); + int e = Exponent(); + + // The current double could be a denormal. + while ((f & kHiddenBit) == 0) + { + f <<= 1; + e--; + } + // Do the final shifts in one go. + f <<= DiyFp.kSignificandSize - kSignificandSize; + e -= DiyFp.kSignificandSize - kSignificandSize; + return new DiyFp(f, e); + } + + // Returns the double's bit as uint64. + public ulong AsUint64() + { + return d64_; + } + + // Returns the next greater double. Returns +infinity on input +infinity. + public double NextDouble() + { + if (d64_ == kInfinity) return new Double(kInfinity).value(); + if (Sign() < 0 && Significand() == 0) + { + // -0.0 + return 0.0; + } + if (Sign() < 0) + { + return new Double(d64_ - 1).value(); + } + else + { + return new Double(d64_ + 1).value(); + } + } + + public double PreviousDouble() + { + if (d64_ == (kInfinity | kSignMask)) return -Infinity(); + if (Sign() < 0) + { + return new Double(d64_ + 1).value(); + } + else + { + if (Significand() == 0) return -0.0; + return new Double(d64_ - 1).value(); + } + } + + public int Exponent() + { + if (IsDenormal()) return kDenormalExponent; + + ulong d64 = AsUint64(); + int biased_e = + (int)((d64 & kExponentMask) >> kPhysicalSignificandSize); + return biased_e - kExponentBias; + } + + public ulong Significand() + { + ulong d64 = AsUint64(); + ulong significand = d64 & kSignificandMask; + if (!IsDenormal()) + { + return significand + kHiddenBit; + } + else + { + return significand; + } + } + + // Returns true if the double is a denormal. + public bool IsDenormal() + { + ulong d64 = AsUint64(); + return (d64 & kExponentMask) == 0; + } + + // We consider denormals not to be special. + // Hence only Infinity and NaN are special. + public bool IsSpecial() + { + ulong d64 = AsUint64(); + return (d64 & kExponentMask) == kExponentMask; + } + + public bool IsNan() + { + ulong d64 = AsUint64(); + return ((d64 & kExponentMask) == kExponentMask) && + ((d64 & kSignificandMask) != 0); + } + + public bool IsInfinite() + { + ulong d64 = AsUint64(); + return ((d64 & kExponentMask) == kExponentMask) && + ((d64 & kSignificandMask) == 0); + } + + public int Sign() + { + ulong d64 = AsUint64(); + return (d64 & kSignMask) == 0 ? 1 : -1; + } + + // Precondition: the value encoded by this Double must be greater or equal + // than +0.0. + public DiyFp UpperBoundary() + { + return new DiyFp(Significand() * 2 + 1, Exponent() - 1); + } + + // Computes the two boundaries of this. + // The bigger boundary (m_plus) is normalized. The lower boundary has the same + // exponent as m_plus. + // Precondition: the value encoded by this Double must be greater than 0. + public void NormalizedBoundaries(out DiyFp out_m_minus, out DiyFp out_m_plus) + { + DiyFp v = this.AsDiyFp(); + var __ = new DiyFp((v.f << 1) + 1, v.e - 1); + var m_plus = DiyFp.Normalize(ref __); + + DiyFp m_minus; + if (LowerBoundaryIsCloser()) + { + m_minus = new DiyFp((v.f << 2) - 1, v.e - 2); + } + else + { + m_minus = new DiyFp((v.f << 1) - 1, v.e - 1); + } + m_minus.f = m_minus.f << (m_minus.e - m_plus.e); + m_minus.e = (m_plus.e); + out_m_plus = m_plus; + out_m_minus = m_minus; + } + + public bool LowerBoundaryIsCloser() + { + // The boundary is closer if the significand is of the form f == 2^p-1 then + // the lower boundary is closer. + // Think of v = 1000e10 and v- = 9999e9. + // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but + // at a distance of 1e8. + // The only exception is for the smallest normal: the largest denormal is + // at the same distance as its successor. + // Note: denormals have the same exponent as the smallest normals. + bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0); + return physical_significand_is_zero && (Exponent() != kDenormalExponent); + } + + public double value() + { + return new UnionDoubleULong { u64 = d64_ }.d; + } + + // Returns the significand size for a given order of magnitude. + // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude. + // This function returns the number of significant binary digits v will have + // once it's encoded into a double. In almost all cases this is equal to + // kSignificandSize. The only exceptions are denormals. They start with + // leading zeroes and their effective significand-size is hence smaller. + public static int SignificandSizeForOrderOfMagnitude(int order) + { + if (order >= (kDenormalExponent + kSignificandSize)) + { + return kSignificandSize; + } + if (order <= kDenormalExponent) return 0; + return order - kDenormalExponent; + } + + public static double Infinity() + { + return new Double(kInfinity).value(); + } + + public static double NaN() + { + return new Double(kNaN).value(); + } + + public static ulong DiyFpToUint64(DiyFp diy_fp) + { + ulong significand = diy_fp.f; + int exponent = diy_fp.e; + while (significand > kHiddenBit + kSignificandMask) + { + significand >>= 1; + exponent++; + } + if (exponent >= kMaxExponent) + { + return kInfinity; + } + if (exponent < kDenormalExponent) + { + return 0; + } + while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) + { + significand <<= 1; + exponent--; + } + ulong biased_exponent; + if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) + { + biased_exponent = 0; + } + else + { + biased_exponent = (ulong)(exponent + kExponentBias); + } + return (significand & kSignificandMask) | + (biased_exponent << kPhysicalSignificandSize); + } + } + + internal struct Single + { + const int kExponentBias = 0x7F + kPhysicalSignificandSize; + const int kDenormalExponent = -kExponentBias + 1; + const int kMaxExponent = 0xFF - kExponentBias; + const uint32_t kInfinity = 0x7F800000; + const uint32_t kNaN = 0x7FC00000; + + public const uint32_t kSignMask = 0x80000000; + public const uint32_t kExponentMask = 0x7F800000; + public const uint32_t kSignificandMask = 0x007FFFFF; + public const uint32_t kHiddenBit = 0x00800000; + public const int kPhysicalSignificandSize = 23; // Excludes the hidden bit. + public const int kSignificandSize = 24; + + uint32_t d32_; + + public Single(float f) + { + this.d32_ = new UnionFloatUInt { f = f }.u32; + } + + // The value encoded by this Single must be greater or equal to +0.0. + // It must not be special (infinity, or NaN). + public DiyFp AsDiyFp() + { + return new DiyFp(Significand(), Exponent()); + } + + // Returns the single's bit as uint64. + public uint32_t AsUint32() + { + return d32_; + } + + public int Exponent() + { + if (IsDenormal()) return kDenormalExponent; + + uint32_t d32 = AsUint32(); + int biased_e = (int)((d32 & kExponentMask) >> kPhysicalSignificandSize); + return biased_e - kExponentBias; + } + + public uint32_t Significand() + { + uint32_t d32 = AsUint32(); + uint32_t significand = d32 & kSignificandMask; + if (!IsDenormal()) + { + return significand + kHiddenBit; + } + else + { + return significand; + } + } + + // Returns true if the single is a denormal. + public bool IsDenormal() + { + uint32_t d32 = AsUint32(); + return (d32 & kExponentMask) == 0; + } + + // We consider denormals not to be special. + // Hence only Infinity and NaN are special. + public bool IsSpecial() + { + uint32_t d32 = AsUint32(); + return (d32 & kExponentMask) == kExponentMask; + } + + public bool IsNan() + { + uint32_t d32 = AsUint32(); + return ((d32 & kExponentMask) == kExponentMask) && + ((d32 & kSignificandMask) != 0); + } + + public bool IsInfinite() + { + uint32_t d32 = AsUint32(); + return ((d32 & kExponentMask) == kExponentMask) && + ((d32 & kSignificandMask) == 0); + } + + public int Sign() + { + uint32_t d32 = AsUint32(); + return (d32 & kSignMask) == 0 ? 1 : -1; + } + + // Computes the two boundaries of this. + // The bigger boundary (m_plus) is normalized. The lower boundary has the same + // exponent as m_plus. + // Precondition: the value encoded by this Single must be greater than 0. + public void NormalizedBoundaries(out DiyFp out_m_minus, out DiyFp out_m_plus) + { + DiyFp v = this.AsDiyFp(); + var __ = new DiyFp((v.f << 1) + 1, v.e - 1); + DiyFp m_plus = DiyFp.Normalize(ref __); + DiyFp m_minus; + if (LowerBoundaryIsCloser()) + { + m_minus = new DiyFp((v.f << 2) - 1, v.e - 2); + } + else + { + m_minus = new DiyFp((v.f << 1) - 1, v.e - 1); + } + m_minus.f = (m_minus.f << (m_minus.e - m_plus.e)); + m_minus.e = (m_plus.e); + out_m_plus = m_plus; + out_m_minus = m_minus; + } + + // Precondition: the value encoded by this Single must be greater or equal + // than +0.0. + public DiyFp UpperBoundary() + { + return new DiyFp(Significand() * 2 + 1, Exponent() - 1); + } + + public bool LowerBoundaryIsCloser() + { + // The boundary is closer if the significand is of the form f == 2^p-1 then + // the lower boundary is closer. + // Think of v = 1000e10 and v- = 9999e9. + // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but + // at a distance of 1e8. + // The only exception is for the smallest normal: the largest denormal is + // at the same distance as its successor. + // Note: denormals have the same exponent as the smallest normals. + bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0); + return physical_significand_is_zero && (Exponent() != kDenormalExponent); + } + + public float value() { return new UnionFloatUInt { u32 = d32_ }.f; } + + public static float Infinity() + { + return new Single(kInfinity).value(); + } + + public static float NaN() + { + return new Single(kNaN).value(); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs.meta new file mode 100644 index 00000000..e291edec --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 430f6699b2401fc4a9e70d227c4be60a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs new file mode 100644 index 00000000..2150d858 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text.Internal +{ + using uint64_t = UInt64; + using int16_t = Int16; + + // https://github.com/google/double-conversion/blob/master/double-conversion/cached-powers.h + // https://github.com/google/double-conversion/blob/master/double-conversion/cached-powers.cc + + internal struct CachedPower + { + public readonly uint64_t significand; + public readonly int16_t binary_exponent; + public readonly int16_t decimal_exponent; + + public CachedPower(ulong significand, short binary_exponent, short decimal_exponent) + { + this.significand = significand; + this.binary_exponent = binary_exponent; + this.decimal_exponent = decimal_exponent; + } + }; + + internal static class PowersOfTenCache + { + static readonly CachedPower[] kCachedPowers = new CachedPower[] + { + new CachedPower (0xfa8fd5a0081c0288, -1220, -348), + new CachedPower (0xbaaee17fa23ebf76, -1193, -340), + new CachedPower (0x8b16fb203055ac76, -1166, -332), + new CachedPower (0xcf42894a5dce35ea, -1140, -324), + new CachedPower (0x9a6bb0aa55653b2d, -1113, -316), + new CachedPower (0xe61acf033d1a45df, -1087, -308), + new CachedPower (0xab70fe17c79ac6ca, -1060, -300), + new CachedPower (0xff77b1fcbebcdc4f, -1034, -292), + new CachedPower (0xbe5691ef416bd60c, -1007, -284), + new CachedPower (0x8dd01fad907ffc3c, -980, -276), + new CachedPower (0xd3515c2831559a83, -954, -268), + new CachedPower (0x9d71ac8fada6c9b5, -927, -260), + new CachedPower (0xea9c227723ee8bcb, -901, -252), + new CachedPower (0xaecc49914078536d, -874, -244), + new CachedPower (0x823c12795db6ce57, -847, -236), + new CachedPower (0xc21094364dfb5637, -821, -228), + new CachedPower (0x9096ea6f3848984f, -794, -220), + new CachedPower (0xd77485cb25823ac7, -768, -212), + new CachedPower (0xa086cfcd97bf97f4, -741, -204), + new CachedPower (0xef340a98172aace5, -715, -196), + new CachedPower (0xb23867fb2a35b28e, -688, -188), + new CachedPower (0x84c8d4dfd2c63f3b, -661, -180), + new CachedPower (0xc5dd44271ad3cdba, -635, -172), + new CachedPower (0x936b9fcebb25c996, -608, -164), + new CachedPower (0xdbac6c247d62a584, -582, -156), + new CachedPower (0xa3ab66580d5fdaf6, -555, -148), + new CachedPower (0xf3e2f893dec3f126, -529, -140), + new CachedPower (0xb5b5ada8aaff80b8, -502, -132), + new CachedPower (0x87625f056c7c4a8b, -475, -124), + new CachedPower (0xc9bcff6034c13053, -449, -116), + new CachedPower (0x964e858c91ba2655, -422, -108), + new CachedPower (0xdff9772470297ebd, -396, -100), + new CachedPower (0xa6dfbd9fb8e5b88f, -369, -92), + new CachedPower (0xf8a95fcf88747d94, -343, -84), + new CachedPower (0xb94470938fa89bcf, -316, -76), + new CachedPower (0x8a08f0f8bf0f156b, -289, -68), + new CachedPower (0xcdb02555653131b6, -263, -60), + new CachedPower (0x993fe2c6d07b7fac, -236, -52), + new CachedPower (0xe45c10c42a2b3b06, -210, -44), + new CachedPower (0xaa242499697392d3, -183, -36), + new CachedPower (0xfd87b5f28300ca0e, -157, -28), + new CachedPower (0xbce5086492111aeb, -130, -20), + new CachedPower (0x8cbccc096f5088cc, -103, -12), + new CachedPower (0xd1b71758e219652c, -77, -4), + new CachedPower (0x9c40000000000000, -50, 4), + new CachedPower (0xe8d4a51000000000, -24, 12), + new CachedPower (0xad78ebc5ac620000, 3, 20), + new CachedPower (0x813f3978f8940984, 30, 28), + new CachedPower (0xc097ce7bc90715b3, 56, 36), + new CachedPower (0x8f7e32ce7bea5c70, 83, 44), + new CachedPower (0xd5d238a4abe98068, 109, 52), + new CachedPower (0x9f4f2726179a2245, 136, 60), + new CachedPower (0xed63a231d4c4fb27, 162, 68), + new CachedPower (0xb0de65388cc8ada8, 189, 76), + new CachedPower (0x83c7088e1aab65db, 216, 84), + new CachedPower (0xc45d1df942711d9a, 242, 92), + new CachedPower (0x924d692ca61be758, 269, 100), + new CachedPower (0xda01ee641a708dea, 295, 108), + new CachedPower (0xa26da3999aef774a, 322, 116), + new CachedPower (0xf209787bb47d6b85, 348, 124), + new CachedPower (0xb454e4a179dd1877, 375, 132), + new CachedPower (0x865b86925b9bc5c2, 402, 140), + new CachedPower (0xc83553c5c8965d3d, 428, 148), + new CachedPower (0x952ab45cfa97a0b3, 455, 156), + new CachedPower (0xde469fbd99a05fe3, 481, 164), + new CachedPower (0xa59bc234db398c25, 508, 172), + new CachedPower (0xf6c69a72a3989f5c, 534, 180), + new CachedPower (0xb7dcbf5354e9bece, 561, 188), + new CachedPower (0x88fcf317f22241e2, 588, 196), + new CachedPower (0xcc20ce9bd35c78a5, 614, 204), + new CachedPower (0x98165af37b2153df, 641, 212), + new CachedPower (0xe2a0b5dc971f303a, 667, 220), + new CachedPower (0xa8d9d1535ce3b396, 694, 228), + new CachedPower (0xfb9b7cd9a4a7443c, 720, 236), + new CachedPower (0xbb764c4ca7a44410, 747, 244), + new CachedPower (0x8bab8eefb6409c1a, 774, 252), + new CachedPower (0xd01fef10a657842c, 800, 260), + new CachedPower (0x9b10a4e5e9913129, 827, 268), + new CachedPower (0xe7109bfba19c0c9d, 853, 276), + new CachedPower (0xac2820d9623bf429, 880, 284), + new CachedPower (0x80444b5e7aa7cf85, 907, 292), + new CachedPower (0xbf21e44003acdd2d, 933, 300), + new CachedPower (0x8e679c2f5e44ff8f, 960, 308), + new CachedPower (0xd433179d9c8cb841, 986, 316), + new CachedPower (0x9e19db92b4e31ba9, 1013, 324), + new CachedPower (0xeb96bf6ebadf77d9, 1039, 332), + new CachedPower (0xaf87023b9bf0ee6b, 1066, 340), + }; + + public const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent. + public const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) + // Difference between the decimal exponents in the table above. + public const int kDecimalExponentDistance = 8; + public const int kMinDecimalExponent = -348; + public const int kMaxDecimalExponent = 340; + + public static void GetCachedPowerForBinaryExponentRange( + int min_exponent, + int max_exponent, + out DiyFp power, + out int decimal_exponent) + { + int kQ = DiyFp.kSignificandSize; + double k = Math.Ceiling((min_exponent + kQ - 1) * kD_1_LOG2_10); + int foo = kCachedPowersOffset; + int index = (foo + (int)(k) - 1) / kDecimalExponentDistance + 1; + + CachedPower cached_power = kCachedPowers[index]; + // (void)max_exponent; // Mark variable as used. + decimal_exponent = cached_power.decimal_exponent; + power = new DiyFp(cached_power.significand, cached_power.binary_exponent); + } + + public static void GetCachedPowerForDecimalExponent(int requested_exponent, + out DiyFp power, + out int found_exponent) + { + int index = (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance; + CachedPower cached_power = kCachedPowers[index]; + power = new DiyFp(cached_power.significand, cached_power.binary_exponent); + found_exponent = cached_power.decimal_exponent; + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs.meta new file mode 100644 index 00000000..fa546e53 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ceade1a2949e8c4686192afcc6315b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs new file mode 100644 index 00000000..0c65eb55 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs @@ -0,0 +1,535 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text.Internal +{ + using uint64_t = UInt64; + + internal struct Vector + { + public readonly byte[] bytes; + public readonly int start; + public readonly int _length; + + public Vector(byte[] bytes, int start, int length) + { + this.bytes = bytes; + this.start = start; + this._length = length; + } + + public byte this[int i] + { + get + { + return bytes[start + i]; + } + set + { + bytes[start + i] = value; + } + } + + public int length() + { + return _length; + } + + public byte first() + { + return bytes[start]; + } + + public byte last() + { + return bytes[_length - 1]; + } + + public bool is_empty() + { + return _length == 0; + } + + public Vector SubVector(int from, int to) + { + return new Vector(this.bytes, start + from, to - from); + } + } + + internal static class StringToDouble + { + [ThreadStatic] + static byte[] copyBuffer; + + static byte[] GetCopyBuffer() + { + if (copyBuffer == null) + { + copyBuffer = new byte[kMaxSignificantDecimalDigits]; + } + return copyBuffer; + } + + // 2^53 = 9007199254740992. + // Any integer with at most 15 decimal digits will hence fit into a double + // (which has a 53bit significand) without loss of precision. + const int kMaxExactDoubleIntegerDecimalDigits = 15; + // 2^64 = 18446744073709551616 > 10^19 + const int kMaxUint64DecimalDigits = 19; + + // Max double: 1.7976931348623157 x 10^308 + // Min non-zero double: 4.9406564584124654 x 10^-324 + // Any x >= 10^309 is interpreted as +infinity. + // Any x <= 10^-324 is interpreted as 0. + // Note that 2.5e-324 (despite being smaller than the min double) will be read + // as non-zero (equal to the min non-zero double). + const int kMaxDecimalPower = 309; + const int kMinDecimalPower = -324; + + // 2^64 = 18446744073709551616 + const uint64_t kMaxUint64 = 0xFFFFFFFFFFFFFFFF; + + static readonly double[] exact_powers_of_ten = new double[]{ + 1.0, // 10^0 + 10.0, + 100.0, + 1000.0, + 10000.0, + 100000.0, + 1000000.0, + 10000000.0, + 100000000.0, + 1000000000.0, + 10000000000.0, // 10^10 + 100000000000.0, + 1000000000000.0, + 10000000000000.0, + 100000000000000.0, + 1000000000000000.0, + 10000000000000000.0, + 100000000000000000.0, + 1000000000000000000.0, + 10000000000000000000.0, + 100000000000000000000.0, // 10^20 + 1000000000000000000000.0, + // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22 + 10000000000000000000000.0 + }; + static readonly int kExactPowersOfTenSize = exact_powers_of_ten.Length; + + // Maximum number of significant digits in the decimal representation. + // In fact the value is 772 (see conversions.cc), but to give us some margin + // we round up to 780. + const int kMaxSignificantDecimalDigits = 780; + + static Vector TrimLeadingZeros(Vector buffer) + { + for (int i = 0; i < buffer.length(); i++) + { + if (buffer[i] != '0') + { + return buffer.SubVector(i, buffer.length()); + } + } + return new Vector(buffer.bytes, buffer.start, 0); + } + + static Vector TrimTrailingZeros(Vector buffer) + { + for (int i = buffer.length() - 1; i >= 0; --i) + { + if (buffer[i] != '0') + { + return buffer.SubVector(0, i + 1); + } + } + return new Vector(buffer.bytes, buffer.start, 0); + } + + + static void CutToMaxSignificantDigits(Vector buffer, + int exponent, + byte[] significant_buffer, + out int significant_exponent) + { + for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) + { + significant_buffer[i] = buffer[i]; + } + // The input buffer has been trimmed. Therefore the last digit must be + // different from '0'. + // ASSERT(buffer[buffer.length() - 1] != '0'); + // Set the last digit to be non-zero. This is sufficient to guarantee + // correct rounding. + significant_buffer[kMaxSignificantDecimalDigits - 1] = (byte)'1'; + significant_exponent = exponent + (buffer.length() - kMaxSignificantDecimalDigits); + } + + // Trims the buffer and cuts it to at most kMaxSignificantDecimalDigits. + // If possible the input-buffer is reused, but if the buffer needs to be + // modified (due to cutting), then the input needs to be copied into the + // buffer_copy_space. + static void TrimAndCut(Vector buffer, int exponent, + byte[] buffer_copy_space, int space_size, + out Vector trimmed, out int updated_exponent) + { + Vector left_trimmed = TrimLeadingZeros(buffer); + Vector right_trimmed = TrimTrailingZeros(left_trimmed); + exponent += left_trimmed.length() - right_trimmed.length(); + if (right_trimmed.length() > kMaxSignificantDecimalDigits) + { + // (void)space_size; // Mark variable as used. + CutToMaxSignificantDigits(right_trimmed, exponent, + buffer_copy_space, out updated_exponent); + trimmed = new Vector(buffer_copy_space, 0, kMaxSignificantDecimalDigits); + } + else + { + trimmed = right_trimmed; + updated_exponent = exponent; + } + } + + + // Reads digits from the buffer and converts them to a uint64. + // Reads in as many digits as fit into a uint64. + // When the string starts with "1844674407370955161" no further digit is read. + // Since 2^64 = 18446744073709551616 it would still be possible read another + // digit if it was less or equal than 6, but this would complicate the code. + static uint64_t ReadUint64(Vector buffer, + out int number_of_read_digits) + { + uint64_t result = 0; + int i = 0; + while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) + { + int digit = buffer[i++] - '0'; + result = 10 * result + (ulong)digit; + } + number_of_read_digits = i; + return result; + } + + // Reads a DiyFp from the buffer. + // The returned DiyFp is not necessarily normalized. + // If remaining_decimals is zero then the returned DiyFp is accurate. + // Otherwise it has been rounded and has error of at most 1/2 ulp. + static void ReadDiyFp(Vector buffer, + out DiyFp result, + out int remaining_decimals) + { + int read_digits; + uint64_t significand = ReadUint64(buffer, out read_digits); + if (buffer.length() == read_digits) + { + result = new DiyFp(significand, 0); + remaining_decimals = 0; + } + else + { + // Round the significand. + if (buffer[read_digits] >= '5') + { + significand++; + } + // Compute the binary exponent. + int exponent = 0; + result = new DiyFp(significand, exponent); + remaining_decimals = buffer.length() - read_digits; + } + } + + + static bool DoubleStrtod(Vector trimmed, + int exponent, + out double result) + { + if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) + { + int read_digits; + // The trimmed input fits into a double. + // If the 10^exponent (resp. 10^-exponent) fits into a double too then we + // can compute the result-double simply by multiplying (resp. dividing) the + // two numbers. + // This is possible because IEEE guarantees that floating-point operations + // return the best possible approximation. + if (exponent < 0 && -exponent < kExactPowersOfTenSize) + { + // 10^-exponent fits into a double. + result = unchecked((double)(ReadUint64(trimmed, out read_digits))); + result /= exact_powers_of_ten[-exponent]; + return true; + } + if (0 <= exponent && exponent < kExactPowersOfTenSize) + { + // 10^exponent fits into a double. + result = unchecked((double)(ReadUint64(trimmed, out read_digits))); + result *= exact_powers_of_ten[exponent]; + return true; + } + int remaining_digits = + kMaxExactDoubleIntegerDecimalDigits - trimmed.length(); + if ((0 <= exponent) && + (exponent - remaining_digits < kExactPowersOfTenSize)) + { + // The trimmed string was short and we can multiply it with + // 10^remaining_digits. As a result the remaining exponent now fits + // into a double too. + result = unchecked((double)(ReadUint64(trimmed, out read_digits))); + result *= exact_powers_of_ten[remaining_digits]; + result *= exact_powers_of_ten[exponent - remaining_digits]; + return true; + } + } + result = 0; + return false; + } + + + // Returns 10^exponent as an exact DiyFp. + // The given exponent must be in the range [1; kDecimalExponentDistance[. + static DiyFp AdjustmentPowerOfTen(int exponent) + { + // Simply hardcode the remaining powers for the given decimal exponent + // distance. + switch (exponent) + { + case 1: return new DiyFp(0xa000000000000000, -60); + case 2: return new DiyFp(0xc800000000000000, -57); + case 3: return new DiyFp(0xfa00000000000000, -54); + case 4: return new DiyFp(0x9c40000000000000, -50); + case 5: return new DiyFp(0xc350000000000000, -47); + case 6: return new DiyFp(0xf424000000000000, -44); + case 7: return new DiyFp(0x9896800000000000, -40); + default: + throw new Exception("unreached code."); + } + } + + // If the function returns true then the result is the correct double. + // Otherwise it is either the correct double or the double that is just below + // the correct double. + static bool DiyFpStrtod(Vector buffer, + int exponent, + out double result) + { + DiyFp input; + int remaining_decimals; + ReadDiyFp(buffer, out input, out remaining_decimals); + // Since we may have dropped some digits the input is not accurate. + // If remaining_decimals is different than 0 than the error is at most + // .5 ulp (unit in the last place). + // We don't want to deal with fractions and therefore keep a common + // denominator. + const int kDenominatorLog = 3; + const int kDenominator = 1 << kDenominatorLog; + // Move the remaining decimals into the exponent. + exponent += remaining_decimals; + uint64_t error = (ulong)(remaining_decimals == 0 ? 0 : kDenominator / 2); + + int old_e = input.e; + input.Normalize(); + error <<= old_e - input.e; + + if (exponent < PowersOfTenCache.kMinDecimalExponent) + { + result = 0.0; + return true; + } + DiyFp cached_power; + int cached_decimal_exponent; + PowersOfTenCache.GetCachedPowerForDecimalExponent(exponent, + out cached_power, + out cached_decimal_exponent); + + if (cached_decimal_exponent != exponent) + { + int adjustment_exponent = exponent - cached_decimal_exponent; + DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent); + input.Multiply(ref adjustment_power); + if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) + { + // The product of input with the adjustment power fits into a 64 bit + // integer. + } + else + { + // The adjustment power is exact. There is hence only an error of 0.5. + error += kDenominator / 2; + } + } + + input.Multiply(ref cached_power); + // The error introduced by a multiplication of a*b equals + // error_a + error_b + error_a*error_b/2^64 + 0.5 + // Substituting a with 'input' and b with 'cached_power' we have + // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp), + // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64 + int error_b = kDenominator / 2; + int error_ab = (error == 0 ? 0 : 1); // We round up to 1. + int fixed_error = kDenominator / 2; + error += (ulong)(error_b + error_ab + fixed_error); + + old_e = input.e; + input.Normalize(); + error <<= old_e - input.e; + + // See if the double's significand changes if we add/subtract the error. + int order_of_magnitude = DiyFp.kSignificandSize + input.e; + int effective_significand_size = Double.SignificandSizeForOrderOfMagnitude(order_of_magnitude); + int precision_digits_count = DiyFp.kSignificandSize - effective_significand_size; + if (precision_digits_count + kDenominatorLog >= DiyFp.kSignificandSize) + { + // This can only happen for very small denormals. In this case the + // half-way multiplied by the denominator exceeds the range of an uint64. + // Simply shift everything to the right. + int shift_amount = (precision_digits_count + kDenominatorLog) - + DiyFp.kSignificandSize + 1; + input.f = (input.f >> shift_amount); + input.e = (input.e + shift_amount); + // We add 1 for the lost precision of error, and kDenominator for + // the lost precision of input.f(). + error = (error >> shift_amount) + 1 + kDenominator; + precision_digits_count -= shift_amount; + } + // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too. + uint64_t one64 = 1; + uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1; + uint64_t precision_bits = input.f & precision_bits_mask; + uint64_t half_way = one64 << (precision_digits_count - 1); + precision_bits *= kDenominator; + half_way *= kDenominator; + DiyFp rounded_input = new DiyFp(input.f >> precision_digits_count, input.e + precision_digits_count); + if (precision_bits >= half_way + error) + { + rounded_input.f = (rounded_input.f + 1); + } + // If the last_bits are too close to the half-way case than we are too + // inaccurate and round down. In this case we return false so that we can + // fall back to a more precise algorithm. + + result = new Double(rounded_input).value(); + if (half_way - error < precision_bits && precision_bits < half_way + error) + { + // Too imprecise. The caller will have to fall back to a slower version. + // However the returned number is guaranteed to be either the correct + // double, or the next-lower double. + return false; + } + else + { + return true; + } + } + + // Returns true if the guess is the correct double. + // Returns false, when guess is either correct or the next-lower double. + static bool ComputeGuess(Vector trimmed, int exponent, + out double guess) + { + if (trimmed.length() == 0) + { + guess = 0.0; + return true; + } + if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) + { + guess = Double.Infinity(); + return true; + } + if (exponent + trimmed.length() <= kMinDecimalPower) + { + guess = 0.0; + return true; + } + + if (DoubleStrtod(trimmed, exponent, out guess) || + DiyFpStrtod(trimmed, exponent, out guess)) + { + return true; + } + if (guess == Double.Infinity()) + { + return true; + } + return false; + } + + public static double? Strtod(Vector buffer, int exponent) + { + byte[] copy_buffer = GetCopyBuffer(); + Vector trimmed; + int updated_exponent; + TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, + out trimmed, out updated_exponent); + exponent = updated_exponent; + + double guess; + var is_correct = ComputeGuess(trimmed, exponent, out guess); + if (is_correct) return guess; + return null; + } + + public static float? Strtof(Vector buffer, int exponent) + { + byte[] copy_buffer = GetCopyBuffer(); + Vector trimmed; + int updated_exponent; + TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, + out trimmed, out updated_exponent); + exponent = updated_exponent; + + double double_guess; + var is_correct = ComputeGuess(trimmed, exponent, out double_guess); + + float float_guess = (float)(double_guess); + if (float_guess == double_guess) + { + // This shortcut triggers for integer values. + return float_guess; + } + + // We must catch double-rounding. Say the double has been rounded up, and is + // now a boundary of a float, and rounds up again. This is why we have to + // look at previous too. + // Example (in decimal numbers): + // input: 12349 + // high-precision (4 digits): 1235 + // low-precision (3 digits): + // when read from input: 123 + // when rounded from high precision: 124. + // To do this we simply look at the neigbors of the correct result and see + // if they would round to the same float. If the guess is not correct we have + // to look at four values (since two different doubles could be the correct + // double). + + double double_next = new Double(double_guess).NextDouble(); + double double_previous = new Double(double_guess).PreviousDouble(); + + float f1 = (float)(double_previous); + // float f2 = float_guess; + float f3 = (float)(double_next); + float f4; + if (is_correct) + { + f4 = f3; + } + else + { + double double_next2 = new Double(double_next).NextDouble(); + f4 = (float)(double_next2); + } + // (void)f2; // Mark variable as used. + + // If the guess doesn't lie near a single-precision boundary we can simply + // return its float-value. + if (f1 == f4) + { + return float_guess; + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs.meta new file mode 100644 index 00000000..551d4e0a --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 12065a632080740419231e5d927b6b2e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs new file mode 100644 index 00000000..67cbe2a1 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs @@ -0,0 +1,625 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text.Internal +{ +#pragma warning disable 660 +#pragma warning disable 661 + + internal struct Iterator + { + byte[] buffer; + int offset; + + public Iterator(byte[] buffer, int offset) + { + this.buffer = buffer; + this.offset = offset; + } + + public byte Value + { + get + { + return buffer[offset]; + } + } + + public static Iterator operator ++(Iterator self) + { + self.offset++; + return self; + } + + public static Iterator operator +(Iterator self, int length) + { + return new Iterator { buffer = self.buffer, offset = self.offset + length }; + } + + public static int operator -(Iterator lhs, Iterator rhs) + { + return lhs.offset - rhs.offset; + } + + public static bool operator ==(Iterator lhs, Iterator rhs) + { + return lhs.offset == rhs.offset; + } + + public static bool operator !=(Iterator lhs, Iterator rhs) + { + return lhs.offset != rhs.offset; + } + + public static bool operator ==(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] == (byte)rhs; + } + + public static bool operator !=(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] != (byte)rhs; + } + + public static bool operator ==(Iterator lhs, byte rhs) + { + return lhs.buffer[lhs.offset] == (byte)rhs; + } + + public static bool operator !=(Iterator lhs, byte rhs) + { + return lhs.buffer[lhs.offset] != (byte)rhs; + } + + public static bool operator >=(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] >= (byte)rhs; + } + + public static bool operator <=(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] <= (byte)rhs; + } + + public static bool operator >(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] > (byte)rhs; + } + + public static bool operator <(Iterator lhs, char rhs) + { + return lhs.buffer[lhs.offset] < (byte)rhs; + } + } + +#pragma warning restore 661 +#pragma warning restore 660 + + // C# API + internal static partial class StringToDoubleConverter + { + [ThreadStatic] + static byte[] kBuffer; + + static byte[] GetBuffer() + { + if (kBuffer == null) + { + kBuffer = new byte[kBufferSize]; + } + return kBuffer; + } + + [ThreadStatic] + static byte[] fallbackBuffer; + + static byte[] GetFallbackBuffer() + { + if (fallbackBuffer == null) + { + fallbackBuffer = new byte[99]; + } + return fallbackBuffer; + } + + public static double ToDouble(byte[] buffer, int offset, out int readCount) + { + return StringToIeee(new Iterator(buffer, offset), buffer.Length - offset, true, out readCount); + } + + public static float ToSingle(byte[] buffer, int offset, out int readCount) + { + return unchecked((float)StringToIeee(new Iterator(buffer, offset), buffer.Length - offset, false, out readCount)); + } + } + + // port + internal static partial class StringToDoubleConverter + { + enum Flags + { + NO_FLAGS = 0, + ALLOW_HEX = 1, // defined but always disallow + ALLOW_OCTALS = 2, + ALLOW_TRAILING_JUNK = 4, + ALLOW_LEADING_SPACES = 8, + ALLOW_TRAILING_SPACES = 16, + ALLOW_SPACES_AFTER_SIGN = 32, + ALLOW_CASE_INSENSIBILITY = 64, // not supported + }; + + const Flags flags_ = Flags.ALLOW_TRAILING_JUNK | Flags.ALLOW_TRAILING_SPACES | Flags.ALLOW_SPACES_AFTER_SIGN; + const double empty_string_value_ = 0.0; + const double junk_string_value_ = double.NaN; + const int kMaxSignificantDigits = 772; + const int kBufferSize = kMaxSignificantDigits + 10; + static readonly byte[] infinity_symbol_ = Encoding.UTF8.GetBytes(double.PositiveInfinity.ToString()); + static readonly byte[] nan_symbol_ = Encoding.UTF8.GetBytes(double.NaN.ToString()); + + static readonly byte[] kWhitespaceTable7 = new byte[] { 32, 13, 10, 9, 11, 12 }; + static readonly int kWhitespaceTable7Length = kWhitespaceTable7.Length; + + static readonly UInt16[] kWhitespaceTable16 = new UInt16[]{ + 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195, + 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279 + }; + static readonly int kWhitespaceTable16Length = kWhitespaceTable16.Length; + + static bool isWhitespace(int x) + { + if (x < 128) + { + for (int i = 0; i < kWhitespaceTable7Length; i++) + { + if (kWhitespaceTable7[i] == x) return true; + } + } + else + { + for (int i = 0; i < kWhitespaceTable16Length; i++) + { + if (kWhitespaceTable16[i] == x) return true; + } + } + return false; + } + + static bool AdvanceToNonspace(ref Iterator current, Iterator end) + { + while (current != end) + { + if (!isWhitespace(current.Value)) return true; + current++; + } + return false; + } + + static bool ConsumeSubString(ref Iterator current, + Iterator end, + byte[] substring) + { + for (int i = 1; i < substring.Length; i++) + { + ++current; + if (current == end || current != substring[i]) + { + return false; + } + } + ++current; + return true; + } + + + // Consumes first character of the str is equal to ch + static bool ConsumeFirstCharacter(ref Iterator iter, + byte[] str, + int offset) + { + return iter.Value == str[offset]; + } + + static double SignedZero(bool sign) + { + return sign ? -0.0 : 0.0; + } + + static double StringToIeee( + Iterator input, + int length, + bool read_as_double, + out int processed_characters_count) + { + Iterator current = input; + Iterator end = input + length; + + processed_characters_count = 0; + + bool allow_trailing_junk = (flags_ & Flags.ALLOW_TRAILING_JUNK) != 0; + bool allow_leading_spaces = (flags_ & Flags.ALLOW_LEADING_SPACES) != 0; + bool allow_trailing_spaces = (flags_ & Flags.ALLOW_TRAILING_SPACES) != 0; + bool allow_spaces_after_sign = (flags_ & Flags.ALLOW_SPACES_AFTER_SIGN) != 0; + // bool allow_case_insensibility = (flags_ & Flags.ALLOW_CASE_INSENSIBILITY) != 0; + + // To make sure that iterator dereferencing is valid the following + // convention is used: + // 1. Each '++current' statement is followed by check for equality to 'end'. + // 2. If AdvanceToNonspace returned false then current == end. + // 3. If 'current' becomes equal to 'end' the function returns or goes to + // 'parsing_done'. + // 4. 'current' is not dereferenced after the 'parsing_done' label. + // 5. Code before 'parsing_done' may rely on 'current != end'. + if (length == 0) return empty_string_value_; + + if (allow_leading_spaces || allow_trailing_spaces) + { + if (!AdvanceToNonspace(ref current, end)) + { + processed_characters_count = (int)(current - input); + return empty_string_value_; + } + if (!allow_leading_spaces && (input != current)) + { + // No leading spaces allowed, but AdvanceToNonspace moved forward. + return junk_string_value_; + } + } + + // The longest form of simplified number is: "-.1eXXX\0". + byte[] buffer = GetBuffer(); // NOLINT: size is known at compile time. + int buffer_pos = 0; + + // Exponent will be adjusted if insignificant digits of the integer part + // or insignificant leading zeros of the fractional part are dropped. + int exponent = 0; + int significant_digits = 0; + int insignificant_digits = 0; + bool nonzero_digit_dropped = false; + + bool sign = false; + + if (current == '+' || current == '-') + { + sign = (current == '-'); + current++; + Iterator next_non_space = current; + // Skip following spaces (if allowed). + if (!AdvanceToNonspace(ref next_non_space, end)) return junk_string_value_; + if (!allow_spaces_after_sign && (current != next_non_space)) + { + return junk_string_value_; + } + current = next_non_space; + } + + if (infinity_symbol_ != null) + { + if (ConsumeFirstCharacter(ref current, infinity_symbol_, 0)) + { + if (!ConsumeSubString(ref current, end, infinity_symbol_)) + { + return junk_string_value_; + } + + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) + { + return junk_string_value_; + } + if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) + { + return junk_string_value_; + } + + processed_characters_count = (current - input); + return sign ? double.NegativeInfinity : double.PositiveInfinity; + } + } + + if (nan_symbol_ != null) + { + if (ConsumeFirstCharacter(ref current, nan_symbol_, 0)) + { + if (!ConsumeSubString(ref current, end, nan_symbol_)) + { + return junk_string_value_; + } + + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) + { + return junk_string_value_; + } + if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) + { + return junk_string_value_; + } + + processed_characters_count = (current - input); + return sign ? -double.NaN : double.NaN; + } + } + + bool leading_zero = false; + if (current == '0') + { + current++; + if (current == end) + { + processed_characters_count = (current - input); + return SignedZero(sign); + } + + leading_zero = true; + + // It could be hexadecimal value. + //if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) + //{ + // ++current; + // if (current == end || !isDigit(*current, 16)) + // { + // return junk_string_value_; // "0x". + // } + + // bool result_is_junk; + // double result = RadixStringToIeee < 4 > (¤t, + // end, + // sign, + // allow_trailing_junk, + // junk_string_value_, + // read_as_double, + // &result_is_junk); + // if (!result_is_junk) + // { + // if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); + // *processed_characters_count = static_cast(current - input); + // } + // return result; + //} + + // Ignore leading zeros in the integer part. + while (current == '0') + { + current++; + if (current == end) + { + processed_characters_count = (current - input); + return SignedZero(sign); + } + } + } + + bool octal = leading_zero && (flags_ & Flags.ALLOW_OCTALS) != 0; + + // Copy significant digits of the integer part (if any) to the buffer. + while (current >= '0' && current <= '9') + { + if (significant_digits < kMaxSignificantDigits) + { + buffer[buffer_pos++] = (current.Value); + significant_digits++; + // Will later check if it's an octal in the buffer. + } + else + { + insignificant_digits++; // Move the digit into the exponential part. + nonzero_digit_dropped = nonzero_digit_dropped || current != '0'; + } + // octal = octal && *current < '8'; + current++; + if (current == end) goto parsing_done; + } + + if (significant_digits == 0) + { + octal = false; + } + + if (current == '.') + { + if (octal && !allow_trailing_junk) return junk_string_value_; + if (octal) goto parsing_done; + + current++; + if (current == end) + { + if (significant_digits == 0 && !leading_zero) + { + return junk_string_value_; + } + else + { + goto parsing_done; + } + } + + if (significant_digits == 0) + { + // octal = false; + // Integer part consists of 0 or is absent. Significant digits start after + // leading zeros (if any). + while (current == '0') + { + ++current; + if (current == end) + { + processed_characters_count = (current - input); + return SignedZero(sign); + } + exponent--; // Move this 0 into the exponent. + } + } + + // There is a fractional part. + // We don't emit a '.', but adjust the exponent instead. + while (current >= '0' && current <= '9') + { + if (significant_digits < kMaxSignificantDigits) + { + buffer[buffer_pos++] = current.Value; + significant_digits++; + exponent--; + } + else + { + // Ignore insignificant digits in the fractional part. + nonzero_digit_dropped = nonzero_digit_dropped || current != '0'; + } + ++current; + if (current == end) goto parsing_done; + } + } + + if (!leading_zero && exponent == 0 && significant_digits == 0) + { + // If leading_zeros is true then the string contains zeros. + // If exponent < 0 then string was [+-]\.0*... + // If significant_digits != 0 the string is not equal to 0. + // Otherwise there are no digits in the string. + return junk_string_value_; + } + + // Parse exponential part. + if (current == 'e' || current == 'E') + { + if (octal && !allow_trailing_junk) return junk_string_value_; + if (octal) goto parsing_done; + ++current; + if (current == end) + { + if (allow_trailing_junk) + { + goto parsing_done; + } + else + { + return junk_string_value_; + } + } + byte exponen_sign = (byte)'+'; + if (current == '+' || current == '-') + { + exponen_sign = current.Value; + ++current; + if (current == end) + { + if (allow_trailing_junk) + { + goto parsing_done; + } + else + { + return junk_string_value_; + } + } + } + + if (current == end || current < '0' || current > '9') + { + if (allow_trailing_junk) + { + goto parsing_done; + } + else + { + return junk_string_value_; + } + } + + const int max_exponent = int.MaxValue / 2; + + int num = 0; + do + { + // Check overflow. + int digit = current.Value - (byte)'0'; + if (num >= max_exponent / 10 + && !(num == max_exponent / 10 && digit <= max_exponent % 10)) + { + num = max_exponent; + } + else + { + num = num * 10 + digit; + } + ++current; + } while (current != end && current >= '0' && current <= '9'); + + exponent += (exponen_sign == '-' ? -num : num); + } + + if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) + { + return junk_string_value_; + } + if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) + { + return junk_string_value_; + } + if (allow_trailing_spaces) + { + AdvanceToNonspace(ref current, end); + } + + parsing_done: + exponent += insignificant_digits; + + //if (octal) + //{ + // double result; + // bool result_is_junk; + // char* start = buffer; + // result = RadixStringToIeee < 3 > (&start, + // buffer + buffer_pos, + // sign, + // allow_trailing_junk, + // junk_string_value_, + // read_as_double, + // &result_is_junk); + // ASSERT(!result_is_junk); + // *processed_characters_count = static_cast(current - input); + // return result; + //} + + if (nonzero_digit_dropped) + { + buffer[buffer_pos++] = (byte)'1'; + exponent--; + } + + buffer[buffer_pos] = (byte)'\0'; + + double? converted; + if (read_as_double) + { + converted = StringToDouble.Strtod(new Vector(buffer, 0, buffer_pos), exponent); + } + else + { + converted = StringToDouble.Strtof(new Vector(buffer, 0, buffer_pos), exponent); + } + + if (converted == null) + { + // read-again + processed_characters_count = (current - input); + + var fallbackbuffer = GetFallbackBuffer(); + if (fallbackBuffer.Length < processed_characters_count) + { + Array.Resize(ref fallbackBuffer, processed_characters_count); + } + var fallbackI = 0; + while (input != current) + { + fallbackbuffer[fallbackI++] = input.Value; + input++; + } + var laststr = Encoding.UTF8.GetString(fallbackbuffer, 0, fallbackI); + return double.Parse(laststr); + } + + processed_characters_count = (current - input); + return sign ? -converted.Value : converted.Value; + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs.meta new file mode 100644 index 00000000..5ab0b499 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3f829391169baba4294e8a24ddf0fc24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs new file mode 100644 index 00000000..c5ed83c3 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs @@ -0,0 +1,483 @@ +using Cysharp.Text.Internal; +using System; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Cysharp.Text +{ + internal static class Int32 + { + ///

0 ~ 9 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNumber(char c) + { + return '0' <= c && c <= '9'; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Parse(ReadOnlySpan s) + { + var value = 0L; + var sign = 1; + + if (s[0] == '-') + { + sign = -1; + } + + for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) + { + if (!IsNumber(s[i])) + { + goto END; + } + + // long.MinValue causes overflow so use unchecked. + value = unchecked(value * 10 + ((byte)s[i] - '0')); + } + + END: + return checked((int)(unchecked(value * sign))); + } + } + + public static class ShimsExtensions + { + public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) + { + if (span.Length == 0) return 0; + fixed (char* src = span) + fixed (byte* dest = bytes) + { + return encoding.GetBytes(src, span.Length, dest, bytes.Length); + } + } + + public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return DoubleToStringConverter.TryFormat(destination, value, out charsWritten); + } + + public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return DoubleToStringConverter.TryFormat(destination, value, out charsWritten); + } + + public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + static string GetFormat(ReadOnlySpan format) + { + if (format.Length == 0) + { + return null; + } + return format.ToString(); + } + + static bool TryWriteInt64(Span buffer, out int charsWritten, long value) + { + var offset = 0; + charsWritten = 0; + long num1 = value, num2, num3, num4, num5, div; + + if (value < 0) + { + if (value == long.MinValue) // -9223372036854775808 + { + if (buffer.Length < 20) { return false; } + buffer[offset++] = (char)'-'; + buffer[offset++] = (char)'9'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'0'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'6'; + buffer[offset++] = (char)'8'; + buffer[offset++] = (char)'5'; + buffer[offset++] = (char)'4'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'5'; + buffer[offset++] = (char)'8'; + buffer[offset++] = (char)'0'; + buffer[offset++] = (char)'8'; + charsWritten = offset; + return true; + } + + if (buffer.Length < 1) { return false; } + buffer[offset++] = (char)'-'; + num1 = unchecked(-value); + } + + // WriteUInt64(inlined) + + if (num1 < 10000) + { + if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } + if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } + if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } + if (buffer.Length < 4) { return false; } + goto L4; + } + else + { + num2 = num1 / 10000; + num1 -= num2 * 10000; + if (num2 < 10000) + { + if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } + if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } + if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } + if (buffer.Length < 8) { return false; } + goto L8; + } + else + { + num3 = num2 / 10000; + num2 -= num3 * 10000; + if (num3 < 10000) + { + if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } + if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } + if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } + if (buffer.Length < 12) { return false; } + goto L12; + } + else + { + num4 = num3 / 10000; + num3 -= num4 * 10000; + if (num4 < 10000) + { + if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } + if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } + if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } + if (buffer.Length < 16) { return false; } + goto L16; + } + else + { + num5 = num4 / 10000; + num4 -= num5 * 10000; + if (num5 < 10000) + { + if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } + if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } + if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } + if (buffer.Length < 20) { return false; } + goto L20; + } + L20: + buffer[offset++] = (char)('0' + (div = (num5 * 8389L) >> 23)); + num5 -= div * 1000; + L19: + buffer[offset++] = (char)('0' + (div = (num5 * 5243L) >> 19)); + num5 -= div * 100; + L18: + buffer[offset++] = (char)('0' + (div = (num5 * 6554L) >> 16)); + num5 -= div * 10; + L17: + buffer[offset++] = (char)('0' + (num5)); + } + L16: + buffer[offset++] = (char)('0' + (div = (num4 * 8389L) >> 23)); + num4 -= div * 1000; + L15: + buffer[offset++] = (char)('0' + (div = (num4 * 5243L) >> 19)); + num4 -= div * 100; + L14: + buffer[offset++] = (char)('0' + (div = (num4 * 6554L) >> 16)); + num4 -= div * 10; + L13: + buffer[offset++] = (char)('0' + (num4)); + } + L12: + buffer[offset++] = (char)('0' + (div = (num3 * 8389L) >> 23)); + num3 -= div * 1000; + L11: + buffer[offset++] = (char)('0' + (div = (num3 * 5243L) >> 19)); + num3 -= div * 100; + L10: + buffer[offset++] = (char)('0' + (div = (num3 * 6554L) >> 16)); + num3 -= div * 10; + L9: + buffer[offset++] = (char)('0' + (num3)); + } + L8: + buffer[offset++] = (char)('0' + (div = (num2 * 8389L) >> 23)); + num2 -= div * 1000; + L7: + buffer[offset++] = (char)('0' + (div = (num2 * 5243L) >> 19)); + num2 -= div * 100; + L6: + buffer[offset++] = (char)('0' + (div = (num2 * 6554L) >> 16)); + num2 -= div * 10; + L5: + buffer[offset++] = (char)('0' + (num2)); + } + L4: + buffer[offset++] = (char)('0' + (div = (num1 * 8389L) >> 23)); + num1 -= div * 1000; + L3: + buffer[offset++] = (char)('0' + (div = (num1 * 5243L) >> 19)); + num1 -= div * 100; + L2: + buffer[offset++] = (char)('0' + (div = (num1 * 6554L) >> 16)); + num1 -= div * 10; + L1: + buffer[offset++] = (char)('0' + (num1)); + + charsWritten = offset; + return true; + } + + static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) + { + ulong num1 = value, num2, num3, num4, num5, div; + charsWritten = 0; + var offset = 0; + + if (num1 < 10000) + { + if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } + if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } + if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } + if (buffer.Length < 4) { return false; } + goto L4; + } + else + { + num2 = num1 / 10000; + num1 -= num2 * 10000; + if (num2 < 10000) + { + if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } + if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } + if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } + if (buffer.Length < 8) { return false; } + goto L8; + } + else + { + num3 = num2 / 10000; + num2 -= num3 * 10000; + if (num3 < 10000) + { + if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } + if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } + if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } + if (buffer.Length < 12) { return false; } + goto L12; + } + else + { + num4 = num3 / 10000; + num3 -= num4 * 10000; + if (num4 < 10000) + { + if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } + if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } + if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } + if (buffer.Length < 16) { return false; } + goto L16; + } + else + { + num5 = num4 / 10000; + num4 -= num5 * 10000; + if (num5 < 10000) + { + if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } + if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } + if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } + if (buffer.Length < 20) { return false; } + goto L20; + } + L20: + buffer[offset++] = (char)('0' + (div = (num5 * 8389UL) >> 23)); + num5 -= div * 1000; + L19: + buffer[offset++] = (char)('0' + (div = (num5 * 5243UL) >> 19)); + num5 -= div * 100; + L18: + buffer[offset++] = (char)('0' + (div = (num5 * 6554UL) >> 16)); + num5 -= div * 10; + L17: + buffer[offset++] = (char)('0' + (num5)); + } + L16: + buffer[offset++] = (char)('0' + (div = (num4 * 8389UL) >> 23)); + num4 -= div * 1000; + L15: + buffer[offset++] = (char)('0' + (div = (num4 * 5243UL) >> 19)); + num4 -= div * 100; + L14: + buffer[offset++] = (char)('0' + (div = (num4 * 6554UL) >> 16)); + num4 -= div * 10; + L13: + buffer[offset++] = (char)('0' + (num4)); + } + L12: + buffer[offset++] = (char)('0' + (div = (num3 * 8389UL) >> 23)); + num3 -= div * 1000; + L11: + buffer[offset++] = (char)('0' + (div = (num3 * 5243UL) >> 19)); + num3 -= div * 100; + L10: + buffer[offset++] = (char)('0' + (div = (num3 * 6554UL) >> 16)); + num3 -= div * 10; + L9: + buffer[offset++] = (char)('0' + (num3)); + } + L8: + buffer[offset++] = (char)('0' + (div = (num2 * 8389UL) >> 23)); + num2 -= div * 1000; + L7: + buffer[offset++] = (char)('0' + (div = (num2 * 5243UL) >> 19)); + num2 -= div * 100; + L6: + buffer[offset++] = (char)('0' + (div = (num2 * 6554UL) >> 16)); + num2 -= div * 10; + L5: + buffer[offset++] = (char)('0' + (num2)); + } + L4: + buffer[offset++] = (char)('0' + (div = (num1 * 8389UL) >> 23)); + num1 -= div * 1000; + L3: + buffer[offset++] = (char)('0' + (div = (num1 * 5243UL) >> 19)); + num1 -= div * 100; + L2: + buffer[offset++] = (char)('0' + (div = (num1 * 6554UL) >> 16)); + num1 -= div * 10; + L1: + buffer[offset++] = (char)('0' + (num1)); + + charsWritten = offset; + return true; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs.meta new file mode 100644 index 00000000..55444f23 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aeb1b3defff24fe47920fb7d01966e52 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Unity.meta b/src/ZString.Unity/Assets/Scripts/ZString/Unity.meta new file mode 100644 index 00000000..fdd0163b --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5a401e97d5c5c0b4699e384a5baf299c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs new file mode 100644 index 00000000..cbb7f1e7 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs @@ -0,0 +1,185 @@ +using System; +using TMPro; + +namespace Cysharp.Text +{ + public static class TextMeshProExtensions + { + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs.meta new file mode 100644 index 00000000..78de3725 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e8ff697dcb687d47a24aeebcfb46817 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16.meta new file mode 100644 index 00000000..9a8a6561 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 873812c508c6fd34bb7dce99fc1a640a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs new file mode 100644 index 00000000..5182c93b --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -0,0 +1,3056 @@ +using System; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { + public void AppendFormat(string format, T0 arg0) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0) + { + AppendFormat(format, arg0); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1) + { + AppendFormat(format, arg0, arg1); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2) + { + AppendFormat(format, arg0, arg1, arg2); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + AppendFormat(format, arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + case 14: + { + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + case 14: + { + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } + case 15: + { + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(size); + format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); + index += size; + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(copyLength); + format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); + index += copyLength; + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta new file mode 100644 index 00000000..0f4556e7 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 939995818389d4748855b4f240115700 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs new file mode 100644 index 00000000..e900deb4 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs @@ -0,0 +1,1538 @@ +using System; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { + public void AppendMany(T0 arg0, T1 arg1) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1) + { + AppendMany(arg0, arg1); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2) + { + AppendMany(arg0, arg1, arg2); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + AppendMany(arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + AppendMany(arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs.meta new file mode 100644 index 00000000..6058e64e --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d025cae7956cb8f4387c9f69827872cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs new file mode 100644 index 00000000..54a422d6 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -0,0 +1,73 @@ +using System; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { + static object CreateFormatter(Type type) + { + if (type == typeof(System.Byte)) + { + return new TryFormat((System.Byte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.DateTime)) + { + return new TryFormat((System.DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.DateTimeOffset)) + { + return new TryFormat((System.DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Decimal)) + { + return new TryFormat((System.Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Double)) + { + return new TryFormat((System.Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Guid)) + { + return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Int16)) + { + return new TryFormat((System.Int16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Int32)) + { + return new TryFormat((System.Int32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Int64)) + { + return new TryFormat((System.Int64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.SByte)) + { + return new TryFormat((System.SByte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Single)) + { + return new TryFormat((System.Single x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.TimeSpan)) + { + return new TryFormat((System.TimeSpan x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.UInt16)) + { + return new TryFormat((System.UInt16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.UInt32)) + { + return new TryFormat((System.UInt32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.UInt64)) + { + return new TryFormat((System.UInt64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta new file mode 100644 index 00000000..4150f972 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e74b3448ff97ca644b3ecb70a63ae365 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs new file mode 100644 index 00000000..0c7eaad5 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -0,0 +1,429 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Byte value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Byte value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.DateTime value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.DateTime value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.DateTimeOffset value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.DateTimeOffset value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Decimal value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Decimal value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Double value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Double value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int16 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int16 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int32 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int32 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int64 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int64 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.SByte value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.SByte value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Single value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Single value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.TimeSpan value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.TimeSpan value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt16 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt16 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt32 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt32 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt64 value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt64 value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Guid value) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Guid value, ReadOnlySpan format) + { + if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta new file mode 100644 index 00000000..e7eb74b6 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84eb008280df72041a1f3f4fd7147292 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs new file mode 100644 index 00000000..189383a4 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -0,0 +1,249 @@ +using System; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder : IDisposable + { + public delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); + + const int ThreadStaticBufferSize = 31111; + const int DefaultBufferSize = 32768; // use 32K default buffer. + + static char newLine1; + static char newLine2; + static bool crlf; + + static Utf16ValueStringBuilder() + { + var newLine = Environment.NewLine.ToCharArray(); + if (newLine.Length == 1) + { + // cr or lf + newLine1 = newLine[0]; + crlf = false; + } + else + { + // crlf(windows) + newLine1 = newLine[0]; + newLine2 = newLine[1]; + crlf = true; + } + } + + [ThreadStatic] + static char[] scratchBuffer; + + char[] buffer; + int index; + + public int Length => index; + public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + + internal void Init(bool disposeImmediately) + { + char[] buf; + if (disposeImmediately) + { + buf = scratchBuffer; + if (buf == null) + { + buf = scratchBuffer = new char[ThreadStaticBufferSize]; + } + } + else + { + buf = ArrayPool.Shared.Rent(DefaultBufferSize); + } + + buffer = buf; + index = 0; + } + + public void Dispose() + { + if (buffer.Length != ThreadStaticBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + buffer = null; + index = 0; + } + + void TryGrow(int sizeHint) + { + if (buffer.Length < index + sizeHint) + { + Grow(sizeHint); + } + } + + void Grow(int sizeHint = 0) + { + var nextSize = buffer.Length * 2; + if (sizeHint != 0) + { + nextSize = Math.Max(nextSize, index + sizeHint); + } + + var newBuffer = ArrayPool.Shared.Rent(nextSize); + + buffer.CopyTo(newBuffer, 0); + if (buffer.Length != ThreadStaticBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + + buffer = newBuffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendNewLine() + { + if (crlf) + { + if (buffer.Length - index < 2) Grow(2); + buffer[index] = newLine1; + buffer[index + 1] = newLine2; + index += 2; + } + else + { + if (buffer.Length - index < 1) Grow(1); + buffer[index] = newLine1; + index += 1; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string value) + { + if (buffer.Length - index < value.Length) + { + Grow(value.Length); + } + + value.CopyTo(0, buffer, index, value.Length); + index += value.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string value) + { + Append(value); + AppendNewLine(); + } + + public void Append(T value) + { + if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + public void AppendLine(T value) + { + Append(value); + AppendNewLine(); + } + + // Output + + public bool TryCopyTo(Span destination, out int charsWritten) + { + if (destination.Length < index) + { + charsWritten = 0; + return false; + } + + charsWritten = index; + buffer.AsSpan(0, index).CopyTo(destination); + return true; + } + + public override string ToString() + { + return new string(buffer, 0, index); + } + + // IBufferWriter like interface. + + public Span GetWritableBuffer(int sizeHint = 0) + { + if ((buffer.Length - index) < sizeHint) + { + Grow(sizeHint); + } + + return buffer.AsSpan(index); + } + + public void Advance(int count) + { + index += count; + } + + void ThrowArgumentException(string paramName) + { + throw new ArgumentException("Can't format argument.", paramName); + } + + void ThrowFormatException() + { + throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); + } + + public static void RegisterTryFormat(TryFormat formatMethod) + { + FormatterCache.TryFormatDelegate = formatMethod; + } + + static class FormatterCache + { + public static TryFormat TryFormatDelegate; + static FormatterCache() + { + var formatter = (TryFormat)CreateFormatter(typeof(T)); + if (formatter == null) + { + if (typeof(T).IsEnum) + { + formatter = new TryFormat(EnumUtil.TryFormatUtf16); + } + else + { + formatter = new TryFormat(TryFormatDefault); + } + } + + TryFormatDelegate = formatter; + } + + static bool TryFormatDefault(T value, Span dest, out int written, ReadOnlySpan format) + { + if (value == null) + { + written = 0; + return true; + } + + var s = value.ToString(); + + // also use this length when result is false. + written = s.Length; + return s.AsSpan().TryCopyTo(dest); + } + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs.meta new file mode 100644 index 00000000..5c5c1bb6 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a63cdeec02e3c54438967c859226bb32 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8.meta new file mode 100644 index 00000000..2ed7a014 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 67d7f0242422cd6459b1e59c73ff46e8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs new file mode 100644 index 00000000..334abc75 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -0,0 +1,2993 @@ +using System; +using System.Buffers; + +namespace Cysharp.Text +{ + public partial struct Utf8ValueStringBuilder + { + public void AppendFormat(string format, T0 arg0) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0) + { + AppendFormat(format, arg0); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1) + { + AppendFormat(format, arg0, arg1); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2) + { + AppendFormat(format, arg0, arg1, arg2); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + AppendFormat(format, arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + case 14: + { + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + goto NEXT_LOOP; + } + case 1: + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + goto NEXT_LOOP; + } + case 2: + { + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + goto NEXT_LOOP; + } + case 3: + { + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + goto NEXT_LOOP; + } + case 4: + { + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + goto NEXT_LOOP; + } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + goto NEXT_LOOP; + } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } + case 13: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } + case 14: + { + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } + case 15: + { + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + goto NEXT_LOOP; + } + default: + ThrowFormatException(); + break; + } + + ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + TryGrow(UTF8NoBom.GetMaxByteCount(size)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); + index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + } + } + } + + public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta new file mode 100644 index 00000000..038b7555 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0787c9daae5b314b8a42fc4d22309c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs new file mode 100644 index 00000000..30b9f992 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs @@ -0,0 +1,1538 @@ +using System; + +namespace Cysharp.Text +{ + public partial struct Utf8ValueStringBuilder + { + public void AppendMany(T0 arg0, T1 arg1) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1) + { + AppendMany(arg0, arg1); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2) + { + AppendMany(arg0, arg1, arg2); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + AppendMany(arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + AppendMany(arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + int written; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + + } + + public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs.meta new file mode 100644 index 00000000..ecb0b1e1 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47a4c76b9b48cd94ea1c8127f8ebe64f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs new file mode 100644 index 00000000..7511ae11 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -0,0 +1,75 @@ +using System; +using System.Buffers; +using System.Buffers.Text; + +namespace Cysharp.Text +{ + public partial struct Utf8ValueStringBuilder + { + static object CreateFormatter(Type type) + { + if (type == typeof(System.Byte)) + { + return new TryFormat((System.Byte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.DateTime)) + { + return new TryFormat((System.DateTime x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.DateTimeOffset)) + { + return new TryFormat((System.DateTimeOffset x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.Decimal)) + { + return new TryFormat((System.Decimal x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.Double)) + { + return new TryFormat((System.Double x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.Guid)) + { + return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.Int16)) + { + return new TryFormat((System.Int16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.Int32)) + { + return new TryFormat((System.Int32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.Int64)) + { + return new TryFormat((System.Int64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.SByte)) + { + return new TryFormat((System.SByte x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.Single)) + { + return new TryFormat((System.Single x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.TimeSpan)) + { + return new TryFormat((System.TimeSpan x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.UInt16)) + { + return new TryFormat((System.UInt16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.UInt32)) + { + return new TryFormat((System.UInt32 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + if (type == typeof(System.UInt64)) + { + return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta new file mode 100644 index 00000000..c07954e8 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba965c020770010408b27ba8fa94fd12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs new file mode 100644 index 00000000..bcf2135c --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -0,0 +1,431 @@ +using System; +using System.Buffers; +using System.Buffers.Text; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public partial struct Utf8ValueStringBuilder + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Byte value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Byte value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.DateTime value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.DateTime value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.DateTimeOffset value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.DateTimeOffset value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Decimal value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Decimal value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Double value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Double value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int16 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int16 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int32 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int32 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int64 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Int64 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.SByte value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.SByte value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Single value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Single value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.TimeSpan value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.TimeSpan value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt16 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt16 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt32 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt32 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt64 value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.UInt64 value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Guid value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Guid value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta new file mode 100644 index 00000000..3fb02d6f --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b686713f7d79dc24ca68a44e1c0a7b8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs new file mode 100644 index 00000000..522e53c4 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -0,0 +1,263 @@ +using System; +using System.Buffers; +using System.IO; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace Cysharp.Text +{ + public partial struct Utf8ValueStringBuilder : IDisposable + { + public delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); + + const int ThreadStaticBufferSize = 64444; + const int DefaultBufferSize = 65536; // use 64K default buffer. + static Encoding UTF8NoBom = new UTF8Encoding(false); + + static byte newLine1; + static byte newLine2; + static bool crlf; + + static Utf8ValueStringBuilder() + { + var newLine = UTF8NoBom.GetBytes(Environment.NewLine); + if (newLine.Length == 1) + { + // cr or lf + newLine1 = newLine[0]; + crlf = false; + } + else + { + // crlf(windows) + newLine1 = newLine[0]; + newLine2 = newLine[1]; + crlf = true; + } + } + + [ThreadStatic] + static byte[] scratchBuffer; + + byte[] buffer; + int index; + + public int Length => index; + public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + + internal void Init(bool disposeImmediately) + { + byte[] buf; + if (disposeImmediately) + { + buf = scratchBuffer; + if (buf == null) + { + buf = scratchBuffer = new byte[ThreadStaticBufferSize]; + } + } + else + { + buf = ArrayPool.Shared.Rent(DefaultBufferSize); + } + + buffer = buf; + index = 0; + } + + public void Dispose() + { + if (buffer.Length != ThreadStaticBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + buffer = null; + index = 0; + } + + void TryGrow(int sizeHint) + { + if (buffer.Length < index + sizeHint) + { + Grow(sizeHint); + } + } + + void Grow(int sizeHint = 0) + { + var nextSize = buffer.Length * 2; + if (sizeHint != 0) + { + nextSize = Math.Max(nextSize, index + sizeHint); + } + + var newBuffer = ArrayPool.Shared.Rent(nextSize); + + buffer.CopyTo(newBuffer, 0); + if (buffer.Length != ThreadStaticBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + + buffer = newBuffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendNewLine() + { + if (crlf) + { + if (buffer.Length - index < 2) Grow(2); + buffer[index] = newLine1; + buffer[index + 1] = newLine2; + index += 2; + } + else + { + if (buffer.Length - index < 1) Grow(1); + buffer[index] = newLine1; + index += 1; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string value) + { + var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); + if (buffer.Length - index < maxLen) + { + Grow(maxLen); + } + + index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string value) + { + Append(value); + AppendNewLine(); + } + + public void Append(T value) + { + if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) + { + Grow(); + if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + public void AppendLine(T value) + { + Append(value); + AppendNewLine(); + } + + // Output + + public bool TryCopyTo(Span destination, out int bytesWritten) + { + if (destination.Length < index) + { + bytesWritten = 0; + return false; + } + + bytesWritten = index; + buffer.AsSpan(0, index).CopyTo(destination); + return true; + } + + public Task CopyToAsync(Stream stream) + { + return stream.WriteAsync(buffer, 0, index); + } + + public override string ToString() + { + return UTF8NoBom.GetString(buffer, 0, index); + } + + // IBufferWriter like interface. + + public Span GetWritableBuffer(int sizeHint = 0) + { + if ((buffer.Length - index) < sizeHint) + { + Grow(sizeHint); + } + + return buffer.AsSpan(index); + } + + public void Advance(int count) + { + index += count; + } + + void ThrowArgumentException(string paramName) + { + throw new ArgumentException("Can't format argument.", paramName); + } + + void ThrowFormatException() + { + throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); + } + + public static void RegisterTryFormat(TryFormat formatMethod) + { + FormatterCache.TryFormatDelegate = formatMethod; + } + + static class FormatterCache + { + public static TryFormat TryFormatDelegate; + static FormatterCache() + { + var formatter = (TryFormat)CreateFormatter(typeof(T)); + if (formatter == null) + { + if (typeof(T).IsEnum) + { + formatter = new TryFormat(EnumUtil.TryFormatUtf8); + } + else + { + formatter = new TryFormat(TryFormatDefault); + } + } + + TryFormatDelegate = formatter; + } + + static bool TryFormatDefault(T value, Span dest, out int written, StandardFormat format) + { + if (value == null) + { + written = 0; + return true; + } + + var s = value.ToString(); + + // also use this length when result is false. + written = UTF8NoBom.GetMaxByteCount(s.Length); + if (dest.Length < written) + { + return false; + } + + written = UTF8NoBom.GetBytes(s.AsSpan(), dest); + return true; + + } + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs.meta new file mode 100644 index 00000000..86ac1b55 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea8889d2a42dc824697d997531ea0c14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs new file mode 100644 index 00000000..2139423b --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs @@ -0,0 +1,250 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + public static partial class ZString + { + public static string Format(string format, T0 arg0) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var sb = new Utf16ValueStringBuilder(); + sb.Init(true); + try + { + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs.meta new file mode 100644 index 00000000..54b423c2 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 46c1d83e619838446ba528f658244b56 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef b/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef new file mode 100644 index 00000000..8e7cc980 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef @@ -0,0 +1,14 @@ +{ + "name": "ZString", + "references": [ + "Unity.TextMeshPro" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [] +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef.meta b/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef.meta new file mode 100644 index 00000000..de79288a --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 33661e06c33d31b4c9223810bf503247 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs new file mode 100644 index 00000000..788cbaed --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -0,0 +1,19 @@ +namespace Cysharp.Text +{ + public static partial class ZString + { + public static Utf16ValueStringBuilder CreateStringBuilder() + { + var builder = new Utf16ValueStringBuilder(); + builder.Init(false); + return builder; + } + + public static Utf8ValueStringBuilder CreateUtf8StringBuilder() + { + var builder = new Utf8ValueStringBuilder(); + builder.Init(false); + return builder; + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs.meta new file mode 100644 index 00000000..3c0d7174 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a82083d5baadea245b3adc1ffd14da2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/ProjectSettings/AudioManager.asset b/src/ZString.Unity/ProjectSettings/AudioManager.asset new file mode 100644 index 00000000..4f31e744 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/AudioManager.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 diff --git a/src/ZString.Unity/ProjectSettings/ClusterInputManager.asset b/src/ZString.Unity/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 00000000..e7886b26 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/src/ZString.Unity/ProjectSettings/DynamicsManager.asset b/src/ZString.Unity/ProjectSettings/DynamicsManager.asset new file mode 100644 index 00000000..4144c06a --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,30 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 0 + m_ReuseCollisionCallbacks: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 diff --git a/src/ZString.Unity/ProjectSettings/EditorBuildSettings.asset b/src/ZString.Unity/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 00000000..82ab0f59 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,11 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: + - enabled: 1 + path: Assets/Scenes/SampleScene.unity + guid: 2cda990e2423bbf4892e6590ba056729 + m_configObjects: {} diff --git a/src/ZString.Unity/ProjectSettings/EditorSettings.asset b/src/ZString.Unity/ProjectSettings/EditorSettings.asset new file mode 100644 index 00000000..8d9e83b0 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/EditorSettings.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 1 + m_SpritePackerMode: 4 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd + m_ProjectGenerationRootNamespace: + m_UserGeneratedProjectSuffix: + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/src/ZString.Unity/ProjectSettings/GraphicsSettings.asset b/src/ZString.Unity/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 00000000..6c2632ad --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,57 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 diff --git a/src/ZString.Unity/ProjectSettings/InputManager.asset b/src/ZString.Unity/ProjectSettings/InputManager.asset new file mode 100644 index 00000000..17c8f538 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/src/ZString.Unity/ProjectSettings/NavMeshAreas.asset b/src/ZString.Unity/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 00000000..3b0b7c3d --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/src/ZString.Unity/ProjectSettings/NetworkManager.asset b/src/ZString.Unity/ProjectSettings/NetworkManager.asset new file mode 100644 index 00000000..5dc6a831 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/NetworkManager.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!149 &1 +NetworkManager: + m_ObjectHideFlags: 0 + m_DebugLevel: 0 + m_Sendrate: 15 + m_AssetToPrefab: {} diff --git a/src/ZString.Unity/ProjectSettings/Physics2DSettings.asset b/src/ZString.Unity/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000000000000000000000000000000000000..71e598122cc35abfe2ba430bdda9b917083f46c4 GIT binary patch literal 4448 zcmeH~O^g&p6vwNv&)Vgj4}RSBqTVC~G&D5K!_p5sK z>ecIy5n|1V5NnSMA=V3VD}IE??cTGme{cV8J172{pP#oZ=x!&NpI<$9`PkOiu9k<- zU5*aCa%}q$v~$-8fv+r22$5jQyzC^Yj?%*C+)9yrY>9+pX_8eJ@}IzOgW?9%6%zDG zNnt^A7PdE`&G{>-6n#=sXucV3^3$zYHb$jai5`Irn#3@l^)?p5m(wd`@xhFxkCGCB6SC8`XNd&TdPB$1Lr^WPM|TarXd3e8vG!l3<)k|a`6Xue)?UMJX&loXopRQw)E z5-BM(A5xsx(Q@-$#qTxnQ;PQ)`1^|AXW(Bbe!qeLsQ4BGzpD6F1K)rf2jlmEf#(!| zu!mbRKSsfEL}HudUBUcg{v20)dl$);=556vGVnJQf7rl3Q2Y@C|6K7M2L7$$JHeOU zzv%z3iuW7%pNj7?@O20-Y&_4fnv-jS313}jlEpJ&0V zYW`lREpbLswo^W)_@f41SNt&pKdSiSJ=_xX?-)4!!*g!g^|gO|&is>q`wU$B_mqKa z|MvIr)IVSOcc6zaj^EP;uH(mhJ@akkIavM=@u;#?E>$f5?_2Qw>KIz6CF)KQvT8+a4YS4%sJE3cPxxs@NHRw#( zZ7!IyOo?NFk?KsNBSP(B#4cP6emL0}Utzml(3@#|@?vyh+ zQJI>y8?lDe)q|SnIMW!Kx+8n_z{8&W1}!Lmdh{wprNED2a&%%Ma$=!^ITVbKPRo$w z7_x3xv?FH(fpueq!fxVBsDX{hjbg`dbZSA!lftBmkGM_;>6Q^zC#pIjECC&HX4JA> zT`BN9w@FiUC!_Zer|izgZJgG^nuIj&`t6_{ z_29DWH;-T?CyIMqcy79hzok%$#v9ZX14vORCy zZk&ileFWMbmnk~t$P~cwMYsqShG4i{4sn;cKM{mev{CeC>`qjh43Goz$ff0MUng`{ zr^5~dS#_~EFhIZ3Ln($~Fr(wEtrutP6G$sB2t_DbVqDmALb`M@;>D9vnn|?_$H7Tm zH5b!EhwToJTWuQmnb4h;cQ$!{%iiRUXFHjj-~Y}3egwX}vgu;hOa6hyyBzw!F&{KX4}e767T`Sb88p${lYe(s}PXtST{UQLpNeIR^T|C{A+@lq#i literal 0 HcmV?d00001 diff --git a/src/ZString.Unity/ProjectSettings/PresetManager.asset b/src/ZString.Unity/ProjectSettings/PresetManager.asset new file mode 100644 index 00000000..636a595b --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/PresetManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + m_DefaultList: [] diff --git a/src/ZString.Unity/ProjectSettings/ProjectSettings.asset b/src/ZString.Unity/ProjectSettings/ProjectSettings.asset new file mode 100644 index 00000000..0f1270c7 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,619 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 17 + productGUID: 8c4adbd344401cd4ab84729f6d4f5fb1 + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: UnityTestTest + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosAppInBackgroundBehavior: 0 + displayResolutionDialog: 1 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidUseSwappy: 0 + androidBlitType: 0 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 0 + graphicsJobs: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + graphicsJobMode: 0 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + vulkanEnableSetSRGBWrite: 0 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 1 + xboxOneEnable7thCore: 1 + vrSettings: + cardboard: + depthFormat: 0 + enableTransitionView: 0 + daydream: + depthFormat: 0 + useSustainedPerformanceMode: 0 + enableVideoLayer: 0 + useProtectedVideoMemory: 0 + minimumSupportedHeadTracking: 0 + maximumSupportedHeadTracking: 1 + hololens: + depthFormat: 1 + depthBufferSharingEnabled: 1 + lumin: + depthFormat: 0 + frameTiming: 2 + enableGLCache: 0 + glCacheMaxBlobSize: 524288 + glCacheMaxFileSize: 8388608 + oculus: + sharedDepthBuffer: 1 + dashSupport: 1 + lowOverheadMode: 0 + enable360StereoCapture: 0 + isWsaHolographicRemotingEnabled: 0 + protectGraphicsMemory: 0 + enableFrameTimingStats: 0 + useHDRDisplay: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: + Standalone: com.Company.ProductName + buildNumber: {} + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 16 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 9.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + iPhoneSplashScreen: {fileID: 0} + iPhoneHighResSplashScreen: {fileID: 0} + iPhoneTallHighResSplashScreen: {fileID: 0} + iPhone47inSplashScreen: {fileID: 0} + iPhone55inPortraitSplashScreen: {fileID: 0} + iPhone55inLandscapeSplashScreen: {fileID: 0} + iPhone58inPortraitSplashScreen: {fileID: 0} + iPhone58inLandscapeSplashScreen: {fileID: 0} + iPadPortraitSplashScreen: {fileID: 0} + iPadHighResPortraitSplashScreen: {fileID: 0} + iPadLandscapeSplashScreen: {fileID: 0} + iPadHighResLandscapeSplashScreen: {fileID: 0} + iPhone65inPortraitSplashScreen: {fileID: 0} + iPhone65inLandscapeSplashScreen: {fileID: 0} + iPhone61inPortraitSplashScreen: {fileID: 0} + iPhone61inLandscapeSplashScreen: {fileID: 0} + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSUseLaunchScreenStoryboard: 0 + iOSLaunchScreenCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + clonedFromGUID: 5f34be1353de5cf4398729fda238591b + templatePackageId: com.unity.template.2d@3.1.0 + templateDefaultScene: Assets/Scenes/SampleScene.unity + AndroidTargetArchitectures: 1 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: '{inproject}: ' + AndroidKeyaliasName: + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 0 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 100 + resolutionDialogBanner: {fileID: 0} + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: [] + m_BuildTargetBatching: [] + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: AndroidPlayer + m_APIs: 150000000b000000 + m_Automatic: 0 + m_BuildTargetVRSettings: [] + m_BuildTargetEnableVuforiaSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + openGLRequireES32: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupLightmapSettings: [] + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 3 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 + spritePackerPolicy: + webGLMemorySize: 16 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLWasmStreaming: 0 + scriptingDefineSymbols: {} + platformArchitecture: {} + scriptingBackend: {} + il2cppCompilerConfiguration: {} + managedStrippingLevel: {} + incrementalIl2cppBuild: {} + allowUnsafeCode: 0 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 0 + gcWBarrierValidation: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: Template_2D + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: Template_2D + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnableGPUVariability: 1 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + XboxOneOverrideIdentityName: + vrEditorSettings: + daydream: + daydreamIconForeground: {fileID: 0} + daydreamIconBackground: {fileID: 0} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + facebookSdkVersion: 7.9.4 + facebookAppId: + facebookCookies: 1 + facebookLogging: 1 + facebookStatus: 1 + facebookXfbml: 0 + facebookFrictionlessRequests: 1 + apiCompatibilityLevel: 6 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + projectName: + organizationId: + cloudEnabled: 0 + enableNativePlatformBackendsForNewInputSystem: 0 + disableOldInputManagerSupport: 0 + legacyClampBlendShapeWeights: 1 diff --git a/src/ZString.Unity/ProjectSettings/ProjectVersion.txt b/src/ZString.Unity/ProjectSettings/ProjectVersion.txt new file mode 100644 index 00000000..83a18014 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 2019.3.0a2 +m_EditorVersionWithRevision: 2019.3.0a2 (fa7740529556) diff --git a/src/ZString.Unity/ProjectSettings/QualitySettings.asset b/src/ZString.Unity/ProjectSettings/QualitySettings.asset new file mode 100644 index 00000000..4ae8c38e --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/QualitySettings.asset @@ -0,0 +1,191 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 3 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 0 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 0 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PSM: 5 + PSP2: 2 + Standalone: 5 + Tizen: 2 + WebGL: 3 + WiiU: 5 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/src/ZString.Unity/ProjectSettings/TagManager.asset b/src/ZString.Unity/ProjectSettings/TagManager.asset new file mode 100644 index 00000000..1c92a784 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/src/ZString.Unity/ProjectSettings/TimeManager.asset b/src/ZString.Unity/ProjectSettings/TimeManager.asset new file mode 100644 index 00000000..06bcc6d2 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.1 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/src/ZString.Unity/ProjectSettings/UnityConnectSettings.asset b/src/ZString.Unity/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 00000000..fa0b1465 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 0 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com + m_Enabled: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_TestMode: 0 + m_InitializeOnStartup: 1 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/src/ZString.Unity/ProjectSettings/VFXManager.asset b/src/ZString.Unity/ProjectSettings/VFXManager.asset new file mode 100644 index 00000000..0ce54343 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/VFXManager.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_RenderPipeSettingsPath: diff --git a/src/ZString.Unity/ProjectSettings/XRSettings.asset b/src/ZString.Unity/ProjectSettings/XRSettings.asset new file mode 100644 index 00000000..482590c1 --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/XRSettings.asset @@ -0,0 +1,10 @@ +{ + "m_SettingKeys": [ + "VR Device Disabled", + "VR Device User Alert" + ], + "m_SettingValues": [ + "False", + "False" + ] +} \ No newline at end of file diff --git a/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs b/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs index 589b966f..0e398e35 100644 --- a/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs +++ b/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs @@ -887,4 +887,4 @@ static bool DoubleToAscii(double v, return fast_worked; } } -} \ No newline at end of file +} diff --git a/src/ZString/Shims/Shims.cs b/src/ZString/Shims/Shims.cs index c5ed83c3..f6dc0ef3 100644 --- a/src/ZString/Shims/Shims.cs +++ b/src/ZString/Shims/Shims.cs @@ -480,4 +480,4 @@ static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) return true; } } -} \ No newline at end of file +} diff --git a/src/ZString/Unity/TextMeshProExtensions.cs b/src/ZString/Unity/TextMeshProExtensions.cs new file mode 100644 index 00000000..cbb7f1e7 --- /dev/null +++ b/src/ZString/Unity/TextMeshProExtensions.cs @@ -0,0 +1,185 @@ +using System; +using TMPro; + +namespace Cysharp.Text +{ + public static class TextMeshProExtensions + { + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + + } +} \ No newline at end of file diff --git a/src/ZString/Unity/TextMeshProExtensions.tt b/src/ZString/Unity/TextMeshProExtensions.tt new file mode 100644 index 00000000..3491e92d --- /dev/null +++ b/src/ZString/Unity/TextMeshProExtensions.tt @@ -0,0 +1,45 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + } + + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + } +#> +using System; +using TMPro; + +namespace Cysharp.Text +{ + public static class TextMeshProExtensions + { +<# for(var i = 1; i <= 16; i++) { #> + public static void SetTextFormat<<#= CreateTypeArgument(i) #>>(this TMP_Text text, string format, <#= CreateParameters(i) #>) + { + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + { + sb.Init(true); + sb.AppendFormat(format, <#= CreateParameterNames(i) #>); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 5965d0a7..71f1105b 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -23,9 +23,15 @@ + + + + TextTemplatingFileGenerator + TextMeshProExtensions.cs + Utf16ValueStringBuilder.AppendMany.cs TextTemplatingFileGenerator @@ -115,4 +121,15 @@ + + + + $(ProjectDir)..\ZString.Unity\Assets\Scripts\ZString\ + + + + + + +
From 62a9b63f9bd633ef7ce4130a8a268bca7540ce7f Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 23:25:23 +0900 Subject: [PATCH 012/139] CI --- .circleci/config.yml | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 801b3c3b..230395f5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,7 +12,52 @@ executors: environment: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true NUGET_XMLDOC_MODE: skip + unity: + # https://hub.docker.com/r/gableroux/unity3d/tags + parameters: + version: {type: string} + docker: + - image: gableroux/unity3d:<< parameters.version >> + go: + docker: + - image: circleci/golang +commands: + unity_activate: + parameters: + unity_version: {type: string} + unity_license: {type: string} + steps: + # get activation file, if fail to activate unity, use this key and activate from https://license.unity3d.com/manual + - run: apt update && apt install libunwind8 -y + - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -logFile -createManualActivationFile || exit 0 + - store_artifacts: + path: Unity_v<< parameters.unity_version >>.alf + destination: /Unity_v<< parameters.unity_version >>.alf + # get from UNITY_LICENSE envvar(base64 encoded(cat foo.ulf | base64 )), this file is generated from above manual activation + - run: echo << parameters.unity_license >> | base64 -di >> .circleci/Unity.ulf + - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .circleci/Unity.ulf || exit 0 jobs: + # create package for Unity + build-unity: + parameters: + unity_version: {type: string} + unity_license: {type: string} + executor: + name: unity + version: << parameters.unity_version >> + steps: + - checkout + - unity_activate: + unity_version: << parameters.unity_version >> + unity_license: << parameters.unity_license >> + - run: + name: Export unitypackage + command: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export + working_directory: src/ZString.Unity + - persist_to_workspace: + root: ./src/ZString.Unity/ + paths: + - ./ZString.Unity.unitypackage build-test: executor: dotnet steps: @@ -36,10 +81,27 @@ jobs: path: src/ZString/bin/Release/ destination: /ZString/ - run: dotnet nuget push ./src/ZString/bin/Release/ZString.${CIRCLE_TAG}.nupkg -s https://www.nuget.org/api/v2/package -k ${NUGET_KEY} + # upload to github by ghr + upload-github: + executor: go + steps: + - attach_workspace: + at: . + - run: go get github.com/tcnksm/ghr + - run: ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} ${CIRCLE_TAG} . + - store_artifacts: + path: ZString.Unity.unitypackage + destination: ZString.Unity.unitypackage workflows: version: 2 default-pipeline: jobs: + - build-unity: + unity_version: 2019.1.2f1 + unity_license: ${UNITY_LICENSE_2019_1} + filters: + tags: + only: /.*/ - build-test: filters: tags: @@ -49,6 +111,14 @@ workflows: tags: only: /.*/ - build-push: + filters: + tags: + only: /^\d\.\d\.\d.*/ + branches: + ignore: /.*/ + - upload-github: + requires: + - build-unity filters: tags: only: /^\d\.\d\.\d.*/ From e7d1d15019ac42361938209cf54101d72c15507b Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 23:26:27 +0900 Subject: [PATCH 013/139] mroe ci --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 230395f5..7ae4e220 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -106,10 +106,10 @@ workflows: filters: tags: only: /.*/ - - test-netcore2: - filters: - tags: - only: /.*/ +# - test-netcore2: +# filters: +# tags: +# only: /.*/ - build-push: filters: tags: From 202661e460c900753033491d6f5c1b2917af7d02 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 23:38:58 +0900 Subject: [PATCH 014/139] more unity ci --- src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs b/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs index 15a8f3b6..b162f23d 100644 --- a/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs +++ b/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs @@ -14,7 +14,7 @@ public static void Export() // configure var root = "Scripts/ZString"; var fileName = string.IsNullOrEmpty(version) ? "ZString.Unity.unitypackage" : $"ZString.Unity.{version}.unitypackage"; - var exportPath = "../../bin/" + fileName; + var exportPath = "./" + fileName; var path = Path.Combine(Application.dataPath, root); var assets = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories) From 80fd77df2749314a6bc4ce4a68456403955ab969 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 23:42:17 +0900 Subject: [PATCH 015/139] readme --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 50e01974..7a2d7b6e 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,55 @@ ZString === [![CircleCI](https://circleci.com/gh/Cysharp/ZString.svg?style=svg)](https://circleci.com/gh/Cysharp/ZString) -WIP - **Z**ero Allocation **String**Builder for .NET Core and Unity. +Currently Preview Release, -0.1.0. + +Getting Started(Unity, with TextMeshPro) +--- +Check the [releases](https://github.com/Cysharp/ZString/releases) page, download `ZString.Unity.unitypackage`. + +```csharp +TextMeshProUGUI text; // TMP_Text +int count = 0; + +void Update() +{ + label.SetTextFormat("Damage: {0}", count++); +} +``` + +SetTextFormat is extension method of `TMP_Text`, there parameter is generics so can avoid boxing, and ZString writes to buffer directly without any ToString allocation. Finally inner buffer copy to `TextMeshPro` buffer so avoid all string allocations. + +``` +public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) +public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1) +// ... +public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) +``` + +Raw API is start from `ZString.CreateStringBuilder();`. + +```csharp +using(var sb = ZString.CreateStringBuilder()) +{ + sb.Append("foo"); + sb.AppendLine(42); + sb.AppendFormat("{0} {1}", "bar", 123.456); + sb.AppendMany(1, "foo", 100, "bar"); + + Debug.Log(sb.ToString()); +} + +// If you want to use only format, use `ZString.Format` instead of `String.Format`. +var str = ZString.Format("foo {0} bar {1}", 42, 123.456); +``` + +Getting Started(.NET Core) +--- + +> PM> Install-Package [ZString](https://www.nuget.org/packages/ZString) + ```csharp using var sb = ZString.CreateStringBuilder(); From 28b0eb7b609a0b45cef0728e5f92e902340be892 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 4 Feb 2020 23:43:47 +0900 Subject: [PATCH 016/139] more readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a2d7b6e..f9d7caa6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ int count = 0; void Update() { - label.SetTextFormat("Damage: {0}", count++); + text.SetTextFormat("Damage: {0}", count++); } ``` From 8f402ac0554bc3876897925b0ad72e9d516683d0 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Tue, 4 Feb 2020 23:53:34 +0900 Subject: [PATCH 017/139] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9d7caa6..3db267ff 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ void Update() SetTextFormat is extension method of `TMP_Text`, there parameter is generics so can avoid boxing, and ZString writes to buffer directly without any ToString allocation. Finally inner buffer copy to `TextMeshPro` buffer so avoid all string allocations. -``` +```csharp public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1) // ... From afbd44ad178c625acaa5bcfe4a0f2e5872204973 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Wed, 5 Feb 2020 00:08:35 +0900 Subject: [PATCH 018/139] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3db267ff..923be853 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Getting Started(Unity, with TextMeshPro) Check the [releases](https://github.com/Cysharp/ZString/releases) page, download `ZString.Unity.unitypackage`. ```csharp +using Cysharp.Text; // namespace + TextMeshProUGUI text; // TMP_Text int count = 0; From 7e7422625d805d4cac83fb8d80ac65dfb3126f70 Mon Sep 17 00:00:00 2001 From: itn3000 Date: Wed, 5 Feb 2020 10:13:01 +0900 Subject: [PATCH 019/139] fix build freeze in dotnet-sdk($ProjectDir is not defined) --- src/ZString/ZString.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 71f1105b..f1d200c6 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -124,10 +124,10 @@ - $(ProjectDir)..\ZString.Unity\Assets\Scripts\ZString\ + $(MSBuildProjectDirectory)\..\ZString.Unity\Assets\Scripts\ZString\ - + From 20abf9d575af371f2b114e51048ebc13a25efa84 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Mon, 10 Feb 2020 09:40:40 +0900 Subject: [PATCH 020/139] WIP --- ZString.sln | 13 +- sandbox/ConsoleApp/Program.cs | 12 +- sandbox/ConsoleAppNet472/Program.cs | 16 +- .../Benchmarks/FormatBenchmark.cs | 44 + .../Benchmarks/FourObjectConcatBenchmark.cs | 70 + .../Benchmarks/VSStringFormatter.cs | 42 + sandbox/PerfBenchmark/PerfBenchmark.csproj | 17 + sandbox/PerfBenchmark/Program.cs | 31 + .../DoubleToStringConverter.cs | 2 +- .../Assets/Scripts/ZString/Shims/Shims.cs | 2 +- .../Utf16/Utf16ValueStringBuilder.Concat.cs | 5609 +++++++++++++++++ ...Utf16ValueStringBuilder.CreateFormatter.cs | 60 +- .../ZString/Utf16ValueStringBuilder.cs | 48 +- .../Utf8/Utf8ValueStringBuilder.Concat.cs} | 668 +- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 27 +- .../Assets/Scripts/ZString/ZString.Concat.cs | 248 + .../Assets/Scripts/ZString/ZString.Format.cs | 68 +- .../Assets/Scripts/ZString/ZString.cs | 120 +- src/ZString/FastNumberWriter.cs | 299 + src/ZString/Number/BitOperations.cs | 284 + src/ZString/Number/BufferEx.cs | 28 + src/ZString/Number/DecimalEx.cs | 44 + src/ZString/Number/FloatEx.cs | 43 + src/ZString/Number/InternalSpanEx.cs | 237 + src/ZString/Number/MathEx.cs | 249 + src/ZString/Number/Number.BigInteger.cs | 1222 ++++ src/ZString/Number/Number.DiyFp.cs | 157 + src/ZString/Number/Number.Dragon4.cs | 525 ++ src/ZString/Number/Number.Formatting.cs | 2539 ++++++++ src/ZString/Number/Number.Grisu3.cs | 1067 ++++ src/ZString/Number/Number.NumberBuffer.cs | 124 + .../Number.NumberToFloatingPointBits.cs | 637 ++ src/ZString/Number/Number.Parsing.cs | 2028 ++++++ src/ZString/Number/NumberFormatInfoEx.cs | 15 + src/ZString/Number/ValueStringBuilder.cs | 309 + .../Utf16ValueStringBuilder.AppendMany.tt | 57 - .../Utf16/Utf16ValueStringBuilder.Concat.cs | 5609 +++++++++++++++++ .../Utf16/Utf16ValueStringBuilder.Concat.tt | 86 + ...Utf16ValueStringBuilder.CreateFormatter.cs | 60 +- ...Utf16ValueStringBuilder.CreateFormatter.tt | 41 +- src/ZString/Utf16ValueStringBuilder.cs | 48 +- .../Utf8ValueStringBuilder.Concat.cs} | 670 +- ...ny.tt => Utf8ValueStringBuilder.Concat.tt} | 13 +- src/ZString/Utf8ValueStringBuilder.cs | 27 +- src/ZString/ZString.Concat.cs | 248 + src/ZString/ZString.Concat.tt | 48 + src/ZString/ZString.Format.cs | 68 +- src/ZString/ZString.Format.tt | 8 +- src/ZString/ZString.cs | 120 +- src/ZString/ZString.csproj | 27 + tests/ZString.Tests/Primitives.cs | 24 +- 51 files changed, 23155 insertions(+), 903 deletions(-) create mode 100644 sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs create mode 100644 sandbox/PerfBenchmark/Benchmarks/FourObjectConcatBenchmark.cs create mode 100644 sandbox/PerfBenchmark/Benchmarks/VSStringFormatter.cs create mode 100644 sandbox/PerfBenchmark/PerfBenchmark.csproj create mode 100644 sandbox/PerfBenchmark/Program.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs rename src/{ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs => ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs} (59%) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs create mode 100644 src/ZString/FastNumberWriter.cs create mode 100644 src/ZString/Number/BitOperations.cs create mode 100644 src/ZString/Number/BufferEx.cs create mode 100644 src/ZString/Number/DecimalEx.cs create mode 100644 src/ZString/Number/FloatEx.cs create mode 100644 src/ZString/Number/InternalSpanEx.cs create mode 100644 src/ZString/Number/MathEx.cs create mode 100644 src/ZString/Number/Number.BigInteger.cs create mode 100644 src/ZString/Number/Number.DiyFp.cs create mode 100644 src/ZString/Number/Number.Dragon4.cs create mode 100644 src/ZString/Number/Number.Formatting.cs create mode 100644 src/ZString/Number/Number.Grisu3.cs create mode 100644 src/ZString/Number/Number.NumberBuffer.cs create mode 100644 src/ZString/Number/Number.NumberToFloatingPointBits.cs create mode 100644 src/ZString/Number/Number.Parsing.cs create mode 100644 src/ZString/Number/NumberFormatInfoEx.cs create mode 100644 src/ZString/Number/ValueStringBuilder.cs delete mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs create mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.Concat.tt rename src/ZString/{Utf16/Utf16ValueStringBuilder.AppendMany.cs => Utf8/Utf8ValueStringBuilder.Concat.cs} (59%) rename src/ZString/Utf8/{Utf8ValueStringBuilder.AppendMany.tt => Utf8ValueStringBuilder.Concat.tt} (76%) create mode 100644 src/ZString/ZString.Concat.cs create mode 100644 src/ZString/ZString.Concat.tt diff --git a/ZString.sln b/ZString.sln index ba5aa221..5f56468f 100644 --- a/ZString.sln +++ b/ZString.sln @@ -17,16 +17,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sandbox", "sandbox", "{A7D7 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0803618F-C4E8-4D37-831E-5D26C5574F49}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZString", "src\ZString\ZString.csproj", "{7B09D422-D19A-457E-ADA0-4CDC2DC581BB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZString", "src\ZString\ZString.csproj", "{7B09D422-D19A-457E-ADA0-4CDC2DC581BB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "sandbox\ConsoleApp\ConsoleApp.csproj", "{9ADF67E1-1872-43D3-882E-607071726FE7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "sandbox\ConsoleApp\ConsoleApp.csproj", "{9ADF67E1-1872-43D3-882E-607071726FE7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZString.Tests", "tests\ZString.Tests\ZString.Tests.csproj", "{62090C00-9727-4375-BE40-ABE2F4D41571}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZString.Tests", "tests\ZString.Tests\ZString.Tests.csproj", "{62090C00-9727-4375-BE40-ABE2F4D41571}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppNet472", "sandbox\ConsoleAppNet472\ConsoleAppNet472.csproj", "{BE8A17AA-504A-410D-B86D-92431B0F5594}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZString.NetCore2Tests", "tests\ZString.NetCore2Tests\ZString.NetCore2Tests.csproj", "{62C44156-F55C-4006-B9A2-108DAB340FAC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PerfBenchmark", "sandbox\PerfBenchmark\PerfBenchmark.csproj", "{D766AEB3-3609-4F1D-8D81-5549F748F372}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -53,6 +55,10 @@ Global {62C44156-F55C-4006-B9A2-108DAB340FAC}.Debug|Any CPU.Build.0 = Debug|Any CPU {62C44156-F55C-4006-B9A2-108DAB340FAC}.Release|Any CPU.ActiveCfg = Release|Any CPU {62C44156-F55C-4006-B9A2-108DAB340FAC}.Release|Any CPU.Build.0 = Release|Any CPU + {D766AEB3-3609-4F1D-8D81-5549F748F372}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D766AEB3-3609-4F1D-8D81-5549F748F372}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D766AEB3-3609-4F1D-8D81-5549F748F372}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D766AEB3-3609-4F1D-8D81-5549F748F372}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -63,6 +69,7 @@ Global {62090C00-9727-4375-BE40-ABE2F4D41571} = {0803618F-C4E8-4D37-831E-5D26C5574F49} {BE8A17AA-504A-410D-B86D-92431B0F5594} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} {62C44156-F55C-4006-B9A2-108DAB340FAC} = {0803618F-C4E8-4D37-831E-5D26C5574F49} + {D766AEB3-3609-4F1D-8D81-5549F748F372} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DF39BF43-3E0E-4F7D-9943-7E50D301234D} diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index b86c1965..44d669bc 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -12,16 +12,8 @@ static void Main(string[] args) static void Run() { - //var f = ZString.Format("abcdef: {0}", "abc"); - //Console.WriteLine(f); - - - //Span buffer = stackalloc char[30]; - - //var ok = ShimsExtensions.TryWriteUInt64(buffer, out var written, 98321412421UL); - //Console.WriteLine(ok); - //Console.WriteLine(written); - + var s = ZString.Concat("a", 100, "b", 200); + Console.WriteLine(s); } } } diff --git a/sandbox/ConsoleAppNet472/Program.cs b/sandbox/ConsoleAppNet472/Program.cs index cf5431d9..a23a8a2d 100644 --- a/sandbox/ConsoleAppNet472/Program.cs +++ b/sandbox/ConsoleAppNet472/Program.cs @@ -11,21 +11,7 @@ class Program { static void Main(string[] args) { - //double d = double.Epsilon; - //Span s = stackalloc char[128]; - - //var ok = ShimsExtensions.TryFormat(d, s, out var written); - //Console.WriteLine(ok); - //Console.WriteLine(written); - //Console.WriteLine(new string(s.Slice(written).ToArray())); - - // ReadOnlySpan hoge = "hugahuga"; - var tako = ZString.Format("hoge{0}hoge{1}", 100, 200); - - // new Utf8ValueStringBuilder(). - - - Console.WriteLine(tako); + } } diff --git a/sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs b/sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs new file mode 100644 index 00000000..adf2ff4f --- /dev/null +++ b/sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs @@ -0,0 +1,44 @@ +using BenchmarkDotNet.Attributes; +using Cysharp.Text; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Formatting; + +namespace PerfBenchmark.Benchmarks +{ + [Config(typeof(BenchmarkConfig))] + public class FormatBenchmark + { + int x; + int y; + string format; + StringBuilder stringBuilder; + + public FormatBenchmark() + { + x = int.Parse("100"); + y = int.Parse("200"); + format = "x:{0}, y:{1}"; + stringBuilder = new StringBuilder(); + } + + [Benchmark] + public string StringFormat() + { + return string.Format(format, x, y); + } + + [Benchmark] + public string ZStringFormat() + { + return ZString.Format(format, x, y); + } + + [Benchmark] + public string StringFormatterFormat() + { + return StringBuffer.Format(format, x, y); + } + } +} diff --git a/sandbox/PerfBenchmark/Benchmarks/FourObjectConcatBenchmark.cs b/sandbox/PerfBenchmark/Benchmarks/FourObjectConcatBenchmark.cs new file mode 100644 index 00000000..43ed472c --- /dev/null +++ b/sandbox/PerfBenchmark/Benchmarks/FourObjectConcatBenchmark.cs @@ -0,0 +1,70 @@ +using BenchmarkDotNet.Attributes; +using Cysharp.Text; +using System.Text; + +namespace PerfBenchmark.Benchmarks +{ + [Config(typeof(BenchmarkConfig))] + public class FourObjectConcatBenchmark + { + int x; + int y; + + public FourObjectConcatBenchmark() + { + x = int.Parse("100"); + y = int.Parse("200"); + } + + [Benchmark] + public string StringPlus() + { + return "x:" + x + ", y:" + y; + } + + [Benchmark] + public string StringConcatObject() + { + return string.Concat("x:", x, ", y:", y); + } + + [Benchmark] + public string ZStringConcat() + { + return ZString.Concat("x:", x, ", y:", y); + } + + [Benchmark] + public string StringBuilder() + { + var sb = new StringBuilder(); + sb.Append("x:"); + sb.Append(x); + sb.Append(", y:"); + sb.Append(y); + return sb.ToString(); + } + + [Benchmark] + public string ZStringBuilder() + { + using var sb = ZString.CreateStringBuilder(); + sb.Append("x:"); + sb.Append(x); + sb.Append(", y:"); + sb.Append(y); + return sb.ToString(); + } + + [Benchmark] + public string ZStringBuilder2() + { + using var sb = ZString.CreateStringBuilder(true); + sb.Append("x:"); + sb.Append(x); + sb.Append(", y:"); + sb.Append(y); + return sb.ToString(); + } + } +} diff --git a/sandbox/PerfBenchmark/Benchmarks/VSStringFormatter.cs b/sandbox/PerfBenchmark/Benchmarks/VSStringFormatter.cs new file mode 100644 index 00000000..e904cf47 --- /dev/null +++ b/sandbox/PerfBenchmark/Benchmarks/VSStringFormatter.cs @@ -0,0 +1,42 @@ +using BenchmarkDotNet.Attributes; +using Cysharp.Text; +using System; +using System.Collections.Generic; +using System.Text; + +namespace PerfBenchmark.Benchmarks +{ + [Config(typeof(BenchmarkConfig))] + public class VSStringFormatter + { + [Benchmark] + public string ZStringConcatInt() + { + return ZString.Concat((int)1); + } + + [Benchmark] + public string ZStringBuilderInt() + { + using var builder = Cysharp.Text.ZString.CreateStringBuilder(); + builder.Append((int)1); + return builder.ToString(); + } + + [Benchmark] + public string StringFormatterInt() + { + var builder = new System.Text.Formatting.StringBuffer(); + builder.Append((int)1, System.Text.Formatting.StringView.Empty); + return builder.ToString(); + } + + [Benchmark] + public string BclStringBuilderInt() + { + var builder = new StringBuilder(); + builder.Append((int)1); + return builder.ToString(); + } + } +} diff --git a/sandbox/PerfBenchmark/PerfBenchmark.csproj b/sandbox/PerfBenchmark/PerfBenchmark.csproj new file mode 100644 index 00000000..6cb78ecb --- /dev/null +++ b/sandbox/PerfBenchmark/PerfBenchmark.csproj @@ -0,0 +1,17 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + + + + + diff --git a/sandbox/PerfBenchmark/Program.cs b/sandbox/PerfBenchmark/Program.cs new file mode 100644 index 00000000..1a8fbebc --- /dev/null +++ b/sandbox/PerfBenchmark/Program.cs @@ -0,0 +1,31 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Running; +using Cysharp.Text; +using System; +using System.Buffers; +using System.Reflection; +using System.Text; + +namespace PerfBenchmark +{ + internal class BenchmarkConfig : ManualConfig + { + public BenchmarkConfig() + { + Add(MemoryDiagnoser.Default); + Add(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1)); + } + } + + public class Program + { + static void Main(string[] args) + { + BenchmarkSwitcher.FromAssembly(Assembly.GetEntryAssembly()).Run(args); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs index 589b966f..0e398e35 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs @@ -887,4 +887,4 @@ static bool DoubleToAscii(double v, return fast_worked; } } -} \ No newline at end of file +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs index c5ed83c3..f6dc0ef3 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs @@ -480,4 +480,4 @@ static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) return true; } } -} \ No newline at end of file +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs new file mode 100644 index 00000000..78c1169b --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs @@ -0,0 +1,5609 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { + public void Concat(T0 arg0) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0) + { + Concat(arg0); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1) + { + Concat(arg0, arg1); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2) + { + Concat(arg0, arg1, arg2); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + Concat(arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + Concat(arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + if (typeof(T12) == typeof(string)) + { + var s12 = Unsafe.As(ref arg12); + if (s12 != null) + { + TryGrow(s12.Length); + s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s12.Length; + } + } + else if (typeof(T12) == typeof(int)) + { + int written = 0; + + var i12 = Unsafe.As(ref arg12); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + if (typeof(T12) == typeof(string)) + { + var s12 = Unsafe.As(ref arg12); + if (s12 != null) + { + TryGrow(s12.Length); + s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s12.Length; + } + } + else if (typeof(T12) == typeof(int)) + { + int written = 0; + + var i12 = Unsafe.As(ref arg12); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + + if (typeof(T13) == typeof(string)) + { + var s13 = Unsafe.As(ref arg13); + if (s13 != null) + { + TryGrow(s13.Length); + s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s13.Length; + } + } + else if (typeof(T13) == typeof(int)) + { + int written = 0; + + var i13 = Unsafe.As(ref arg13); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + if (typeof(T12) == typeof(string)) + { + var s12 = Unsafe.As(ref arg12); + if (s12 != null) + { + TryGrow(s12.Length); + s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s12.Length; + } + } + else if (typeof(T12) == typeof(int)) + { + int written = 0; + + var i12 = Unsafe.As(ref arg12); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + + if (typeof(T13) == typeof(string)) + { + var s13 = Unsafe.As(ref arg13); + if (s13 != null) + { + TryGrow(s13.Length); + s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s13.Length; + } + } + else if (typeof(T13) == typeof(int)) + { + int written = 0; + + var i13 = Unsafe.As(ref arg13); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + + if (typeof(T14) == typeof(string)) + { + var s14 = Unsafe.As(ref arg14); + if (s14 != null) + { + TryGrow(s14.Length); + s14.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s14.Length; + } + } + else if (typeof(T14) == typeof(int)) + { + int written = 0; + + var i14 = Unsafe.As(ref arg14); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + if (typeof(T12) == typeof(string)) + { + var s12 = Unsafe.As(ref arg12); + if (s12 != null) + { + TryGrow(s12.Length); + s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s12.Length; + } + } + else if (typeof(T12) == typeof(int)) + { + int written = 0; + + var i12 = Unsafe.As(ref arg12); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + + if (typeof(T13) == typeof(string)) + { + var s13 = Unsafe.As(ref arg13); + if (s13 != null) + { + TryGrow(s13.Length); + s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s13.Length; + } + } + else if (typeof(T13) == typeof(int)) + { + int written = 0; + + var i13 = Unsafe.As(ref arg13); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + + if (typeof(T14) == typeof(string)) + { + var s14 = Unsafe.As(ref arg14); + if (s14 != null) + { + TryGrow(s14.Length); + s14.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s14.Length; + } + } + else if (typeof(T14) == typeof(int)) + { + int written = 0; + + var i14 = Unsafe.As(ref arg14); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + } + + if (typeof(T15) == typeof(string)) + { + var s15 = Unsafe.As(ref arg15); + if (s15 != null) + { + TryGrow(s15.Length); + s15.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s15.Length; + } + } + else if (typeof(T15) == typeof(int)) + { + int written = 0; + + var i15 = Unsafe.As(ref arg15); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i15)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i15)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 54a422d6..4199c437 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -6,65 +6,65 @@ public partial struct Utf16ValueStringBuilder { static object CreateFormatter(Type type) { - if (type == typeof(System.Byte)) - { - return new TryFormat((System.Byte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.DateTime)) - { - return new TryFormat((System.DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.DateTimeOffset)) + if (type == typeof(System.SByte)) { - return new TryFormat((System.DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.SByte x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Decimal)) + if (type == typeof(System.Int16)) { - return new TryFormat((System.Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int16 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Double)) + if (type == typeof(System.Int32)) { - return new TryFormat((System.Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int32 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Guid)) + if (type == typeof(System.Int64)) { - return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int64 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Int16)) + if (type == typeof(System.Byte)) { - return new TryFormat((System.Int16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Byte x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Int32)) + if (type == typeof(System.UInt16)) { - return new TryFormat((System.Int32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt16 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Int64)) + if (type == typeof(System.UInt32)) { - return new TryFormat((System.Int64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt32 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.SByte)) + if (type == typeof(System.UInt64)) { - return new TryFormat((System.SByte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt64 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } if (type == typeof(System.Single)) { return new TryFormat((System.Single x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } + if (type == typeof(System.Double)) + { + return new TryFormat((System.Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } if (type == typeof(System.TimeSpan)) { return new TryFormat((System.TimeSpan x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(System.UInt16)) + if (type == typeof(System.DateTime)) { - return new TryFormat((System.UInt16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(System.UInt32)) + if (type == typeof(System.DateTimeOffset)) { - return new TryFormat((System.UInt32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(System.UInt64)) + if (type == typeof(System.Decimal)) { - return new TryFormat((System.UInt64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Guid)) + { + return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } return null; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 189383a4..c2181024 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -44,7 +44,8 @@ static Utf16ValueStringBuilder() public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); - internal void Init(bool disposeImmediately) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Utf16ValueStringBuilder(bool disposeImmediately) { char[] buf; if (disposeImmediately) @@ -64,6 +65,7 @@ internal void Init(bool disposeImmediately) index = 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (buffer.Length != ThreadStaticBufferSize) @@ -74,6 +76,11 @@ public void Dispose() index = 0; } + public void Clear() + { + index = 0; + } + void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) @@ -119,6 +126,24 @@ public void AppendNewLine() } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char value) + { + if (buffer.Length - index < 1) + { + Grow(1); + } + + buffer[index++] = value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(char value) + { + Append(value); + AppendNewLine(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { @@ -209,7 +234,7 @@ public static void RegisterTryFormat(TryFormat formatMethod) FormatterCache.TryFormatDelegate = formatMethod; } - static class FormatterCache + public static class FormatterCache { public static TryFormat TryFormatDelegate; static FormatterCache() @@ -221,6 +246,10 @@ static FormatterCache() { formatter = new TryFormat(EnumUtil.TryFormatUtf16); } + else if (typeof(T) == typeof(string)) + { + formatter = new TryFormat(TryFormatString); + } else { formatter = new TryFormat(TryFormatDefault); @@ -230,6 +259,21 @@ static FormatterCache() TryFormatDelegate = formatter; } + static bool TryFormatString(T value, Span dest, out int written, ReadOnlySpan format) + { + var s = value as string; + + if (s == null) + { + written = 0; + return true; + } + + // also use this length when result is false. + written = s.Length; + return s.AsSpan().TryCopyTo(dest); + } + static bool TryFormatDefault(T value, Span dest, out int written, ReadOnlySpan format) { if (value == null) diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs similarity index 59% rename from src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs rename to src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs index 30b9f992..4ee6f9c9 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs @@ -4,24 +4,48 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder { - public void AppendMany(T0 arg0, T1 arg1) + public void Concat(T0 arg0) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + } + + public void ConcatLine(T0 arg0) + { + Concat(arg0); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1) + { + int written; + var span = buffer.AsSpan(); + + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } @@ -30,40 +54,41 @@ public void AppendMany(T0 arg0, T1 arg1) } - public void AppendManyLine(T0 arg0, T1 arg1) + public void ConcatLine(T0 arg0, T1 arg1) { - AppendMany(arg0, arg1); + Concat(arg0, arg1); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2) + public void Concat(T0 arg0, T1 arg1, T2 arg2) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } @@ -72,50 +97,51 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2) } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2) { - AppendMany(arg0, arg1, arg2); + Concat(arg0, arg1, arg2); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } @@ -124,60 +150,61 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { - AppendMany(arg0, arg1, arg2, arg3); + Concat(arg0, arg1, arg2, arg3); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } @@ -186,70 +213,71 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { - AppendMany(arg0, arg1, arg2, arg3, arg4); + Concat(arg0, arg1, arg2, arg3, arg4); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } @@ -258,80 +286,81 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5); + Concat(arg0, arg1, arg2, arg3, arg4, arg5); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } @@ -340,90 +369,91 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } @@ -432,100 +462,101 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } @@ -534,110 +565,111 @@ public void AppendMany(T0 arg0, T1 arg1, T2 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } @@ -646,120 +678,121 @@ public void AppendMany(T0 arg0, T1 arg1, } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } @@ -768,130 +801,131 @@ public void AppendMany(T0 arg0, T1 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } @@ -900,140 +934,141 @@ public void AppendMany(T0 arg0 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg12)); } @@ -1042,150 +1077,151 @@ public void AppendMany(T0 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg12)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg13)); } @@ -1194,160 +1230,161 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg12)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg13)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg14)); } @@ -1356,170 +1393,171 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg12)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg13)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg14)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg15, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg15, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg15)); } @@ -1528,9 +1566,9 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); AppendNewLine(); } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 522e53c4..935f38af 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -46,7 +46,8 @@ static Utf8ValueStringBuilder() public int Length => index; public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); - internal void Init(bool disposeImmediately) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Utf8ValueStringBuilder(bool disposeImmediately) { byte[] buf; if (disposeImmediately) @@ -66,6 +67,7 @@ internal void Init(bool disposeImmediately) index = 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (buffer.Length != ThreadStaticBufferSize) @@ -121,6 +123,29 @@ public void AppendNewLine() } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void Append(char value) + { + var maxLen = UTF8NoBom.GetMaxByteCount(1); + if (buffer.Length - index < maxLen) + { + Grow(maxLen); + } + + fixed (byte* bp = &buffer[index]) + { + index += UTF8NoBom.GetBytes(&value, 1, bp, maxLen); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(char value) + { + Append(value); + AppendNewLine(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs new file mode 100644 index 00000000..a5535be2 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs @@ -0,0 +1,248 @@ +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public static partial class ZString + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs index 2139423b..1860dae7 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs @@ -1,15 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Runtime.CompilerServices; namespace Cysharp.Text { public static partial class ZString { + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0); @@ -21,10 +19,10 @@ public static string Format(string format, T0 arg0) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1); @@ -36,10 +34,10 @@ public static string Format(string format, T0 arg0, T1 arg1) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2); @@ -51,10 +49,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2 } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3); @@ -66,10 +64,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); @@ -81,10 +79,10 @@ public static string Format(string format, T0 arg0, T1 arg1, } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); @@ -96,10 +94,10 @@ public static string Format(string format, T0 arg0, T1 a } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); @@ -111,10 +109,10 @@ public static string Format(string format, T0 arg0, } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); @@ -126,10 +124,10 @@ public static string Format(string format, T0 ar } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); @@ -141,10 +139,10 @@ public static string Format(string format, T } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); @@ -156,10 +154,10 @@ public static string Format(string forma } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); @@ -171,10 +169,10 @@ public static string Format(string } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); @@ -186,10 +184,10 @@ public static string Format(st } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); @@ -201,10 +199,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); @@ -216,10 +214,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); @@ -231,10 +229,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 788cbaed..33c62086 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -1,19 +1,125 @@ -namespace Cysharp.Text +using System; +using System.Buffers; +using System.Collections.Generic; + +namespace Cysharp.Text { public static partial class ZString { public static Utf16ValueStringBuilder CreateStringBuilder() { - var builder = new Utf16ValueStringBuilder(); - builder.Init(false); - return builder; + return new Utf16ValueStringBuilder(false); } public static Utf8ValueStringBuilder CreateUtf8StringBuilder() { - var builder = new Utf8ValueStringBuilder(); - builder.Init(false); - return builder; + return new Utf8ValueStringBuilder(false); + } + + public static Utf16ValueStringBuilder CreateStringBuilder(bool notNested) + { + return new Utf16ValueStringBuilder(notNested); + } + + public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) + { + return new Utf8ValueStringBuilder(notNested); + } + + public static string Join(char separator, params T[] values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Join(char separator, IEnumerable values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + var isFirst = false; + foreach (var item in values) + { + if (!isFirst) + { + sb.Append(separator); + } + else + { + isFirst = true; + } + sb.Append(item); + } + + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Join(string separator, params T[] values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Join(string separator, IEnumerable values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + var isFirst = false; + foreach (var item in values) + { + if (!isFirst) + { + sb.Append(separator); + } + else + { + isFirst = true; + } + sb.Append(item); + } + + return sb.ToString(); + } + finally + { + sb.Dispose(); + } } } } diff --git a/src/ZString/FastNumberWriter.cs b/src/ZString/FastNumberWriter.cs new file mode 100644 index 00000000..bd84dd41 --- /dev/null +++ b/src/ZString/FastNumberWriter.cs @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + internal static class FastNumberWriter + { + // Faster than .NET Core .TryFormat without format string. + + public static bool TryWriteInt64(Span buffer, out int charsWritten, long value) + { + var offset = 0; + charsWritten = 0; + long num1 = value, num2, num3, num4, num5, div; + + if (value < 0) + { + if (value == long.MinValue) // -9223372036854775808 + { + if (buffer.Length < 20) { return false; } + buffer[offset++] = (char)'-'; + buffer[offset++] = (char)'9'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'0'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'6'; + buffer[offset++] = (char)'8'; + buffer[offset++] = (char)'5'; + buffer[offset++] = (char)'4'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'5'; + buffer[offset++] = (char)'8'; + buffer[offset++] = (char)'0'; + buffer[offset++] = (char)'8'; + charsWritten = offset; + return true; + } + + if (buffer.Length < 1) { return false; } + buffer[offset++] = (char)'-'; + num1 = unchecked(-value); + } + + // WriteUInt64(inlined) + + if (num1 < 10000) + { + if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } + if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } + if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } + if (buffer.Length < 4) { return false; } + goto L4; + } + else + { + num2 = num1 / 10000; + num1 -= num2 * 10000; + if (num2 < 10000) + { + if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } + if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } + if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } + if (buffer.Length < 8) { return false; } + goto L8; + } + else + { + num3 = num2 / 10000; + num2 -= num3 * 10000; + if (num3 < 10000) + { + if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } + if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } + if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } + if (buffer.Length < 12) { return false; } + goto L12; + } + else + { + num4 = num3 / 10000; + num3 -= num4 * 10000; + if (num4 < 10000) + { + if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } + if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } + if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } + if (buffer.Length < 16) { return false; } + goto L16; + } + else + { + num5 = num4 / 10000; + num4 -= num5 * 10000; + if (num5 < 10000) + { + if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } + if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } + if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } + if (buffer.Length < 20) { return false; } + goto L20; + } + L20: + buffer[offset++] = (char)('0' + (div = (num5 * 8389L) >> 23)); + num5 -= div * 1000; + L19: + buffer[offset++] = (char)('0' + (div = (num5 * 5243L) >> 19)); + num5 -= div * 100; + L18: + buffer[offset++] = (char)('0' + (div = (num5 * 6554L) >> 16)); + num5 -= div * 10; + L17: + buffer[offset++] = (char)('0' + (num5)); + } + L16: + buffer[offset++] = (char)('0' + (div = (num4 * 8389L) >> 23)); + num4 -= div * 1000; + L15: + buffer[offset++] = (char)('0' + (div = (num4 * 5243L) >> 19)); + num4 -= div * 100; + L14: + buffer[offset++] = (char)('0' + (div = (num4 * 6554L) >> 16)); + num4 -= div * 10; + L13: + buffer[offset++] = (char)('0' + (num4)); + } + L12: + buffer[offset++] = (char)('0' + (div = (num3 * 8389L) >> 23)); + num3 -= div * 1000; + L11: + buffer[offset++] = (char)('0' + (div = (num3 * 5243L) >> 19)); + num3 -= div * 100; + L10: + buffer[offset++] = (char)('0' + (div = (num3 * 6554L) >> 16)); + num3 -= div * 10; + L9: + buffer[offset++] = (char)('0' + (num3)); + } + L8: + buffer[offset++] = (char)('0' + (div = (num2 * 8389L) >> 23)); + num2 -= div * 1000; + L7: + buffer[offset++] = (char)('0' + (div = (num2 * 5243L) >> 19)); + num2 -= div * 100; + L6: + buffer[offset++] = (char)('0' + (div = (num2 * 6554L) >> 16)); + num2 -= div * 10; + L5: + buffer[offset++] = (char)('0' + (num2)); + } + L4: + buffer[offset++] = (char)('0' + (div = (num1 * 8389L) >> 23)); + num1 -= div * 1000; + L3: + buffer[offset++] = (char)('0' + (div = (num1 * 5243L) >> 19)); + num1 -= div * 100; + L2: + buffer[offset++] = (char)('0' + (div = (num1 * 6554L) >> 16)); + num1 -= div * 10; + L1: + buffer[offset++] = (char)('0' + (num1)); + + charsWritten = offset; + return true; + } + + public static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) + { + ulong num1 = value, num2, num3, num4, num5, div; + charsWritten = 0; + var offset = 0; + + if (num1 < 10000) + { + if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } + if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } + if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } + if (buffer.Length < 4) { return false; } + goto L4; + } + else + { + num2 = num1 / 10000; + num1 -= num2 * 10000; + if (num2 < 10000) + { + if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } + if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } + if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } + if (buffer.Length < 8) { return false; } + goto L8; + } + else + { + num3 = num2 / 10000; + num2 -= num3 * 10000; + if (num3 < 10000) + { + if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } + if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } + if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } + if (buffer.Length < 12) { return false; } + goto L12; + } + else + { + num4 = num3 / 10000; + num3 -= num4 * 10000; + if (num4 < 10000) + { + if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } + if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } + if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } + if (buffer.Length < 16) { return false; } + goto L16; + } + else + { + num5 = num4 / 10000; + num4 -= num5 * 10000; + if (num5 < 10000) + { + if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } + if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } + if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } + if (buffer.Length < 20) { return false; } + goto L20; + } + L20: + buffer[offset++] = (char)('0' + (div = (num5 * 8389UL) >> 23)); + num5 -= div * 1000; + L19: + buffer[offset++] = (char)('0' + (div = (num5 * 5243UL) >> 19)); + num5 -= div * 100; + L18: + buffer[offset++] = (char)('0' + (div = (num5 * 6554UL) >> 16)); + num5 -= div * 10; + L17: + buffer[offset++] = (char)('0' + (num5)); + } + L16: + buffer[offset++] = (char)('0' + (div = (num4 * 8389UL) >> 23)); + num4 -= div * 1000; + L15: + buffer[offset++] = (char)('0' + (div = (num4 * 5243UL) >> 19)); + num4 -= div * 100; + L14: + buffer[offset++] = (char)('0' + (div = (num4 * 6554UL) >> 16)); + num4 -= div * 10; + L13: + buffer[offset++] = (char)('0' + (num4)); + } + L12: + buffer[offset++] = (char)('0' + (div = (num3 * 8389UL) >> 23)); + num3 -= div * 1000; + L11: + buffer[offset++] = (char)('0' + (div = (num3 * 5243UL) >> 19)); + num3 -= div * 100; + L10: + buffer[offset++] = (char)('0' + (div = (num3 * 6554UL) >> 16)); + num3 -= div * 10; + L9: + buffer[offset++] = (char)('0' + (num3)); + } + L8: + buffer[offset++] = (char)('0' + (div = (num2 * 8389UL) >> 23)); + num2 -= div * 1000; + L7: + buffer[offset++] = (char)('0' + (div = (num2 * 5243UL) >> 19)); + num2 -= div * 100; + L6: + buffer[offset++] = (char)('0' + (div = (num2 * 6554UL) >> 16)); + num2 -= div * 10; + L5: + buffer[offset++] = (char)('0' + (num2)); + } + L4: + buffer[offset++] = (char)('0' + (div = (num1 * 8389UL) >> 23)); + num1 -= div * 1000; + L3: + buffer[offset++] = (char)('0' + (div = (num1 * 5243UL) >> 19)); + num1 -= div * 100; + L2: + buffer[offset++] = (char)('0' + (div = (num1 * 6554UL) >> 16)); + num1 -= div * 10; + L1: + buffer[offset++] = (char)('0' + (num1)); + + charsWritten = offset; + return true; + } + } +} diff --git a/src/ZString/Number/BitOperations.cs b/src/ZString/Number/BitOperations.cs new file mode 100644 index 00000000..978a99cb --- /dev/null +++ b/src/ZString/Number/BitOperations.cs @@ -0,0 +1,284 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Some routines inspired by the Stanford Bit Twiddling Hacks by Sean Eron Anderson: +// http://graphics.stanford.edu/~seander/bithacks.html + +namespace System.Numerics +{ + /// + /// Utility methods for intrinsic bit-twiddling operations. + /// The methods use hardware intrinsics when available on the underlying platform, + /// otherwise they use optimized software fallbacks. + /// + public static class BitOperations + { + // C# no-alloc optimization that directly wraps the data section of the dll (similar to string constants) + // https://github.com/dotnet/roslyn/pull/24621 + + private static ReadOnlySpan TrailingZeroCountDeBruijn => new byte[32] + { + 00, 01, 28, 02, 29, 14, 24, 03, + 30, 22, 20, 15, 25, 17, 04, 08, + 31, 27, 13, 23, 21, 19, 16, 07, + 26, 12, 18, 06, 11, 05, 10, 09 + }; + + private static ReadOnlySpan Log2DeBruijn => new byte[32] + { + 00, 09, 01, 10, 13, 21, 02, 29, + 11, 14, 16, 18, 22, 25, 03, 30, + 08, 12, 20, 28, 15, 17, 24, 07, + 19, 27, 23, 06, 26, 05, 04, 31 + }; + + /// + /// Count the number of leading zero bits in a mask. + /// Similar in behavior to the x86 instruction LZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LeadingZeroCount(uint value) + { + // Unguarded fallback contract is 0->31 + if (value == 0) + { + return 32; + } + + return 31 - Log2SoftwareFallback(value); + } + + /// + /// Count the number of leading zero bits in a mask. + /// Similar in behavior to the x86 instruction LZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LeadingZeroCount(ulong value) + { + uint hi = (uint)(value >> 32); + + if (hi == 0) + { + return 32 + LeadingZeroCount((uint)value); + } + + return LeadingZeroCount(hi); + } + + /// + /// Returns the integer (floor) log of the specified value, base 2. + /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Log2(uint value) + { + // Fallback contract is 0->0 + return Log2SoftwareFallback(value); + } + + /// + /// Returns the integer (floor) log of the specified value, base 2. + /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Log2(ulong value) + { + uint hi = (uint)(value >> 32); + + if (hi == 0) + { + return Log2((uint)value); + } + + return 32 + Log2(hi); + } + + /// + /// Returns the integer (floor) log of the specified value, base 2. + /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. + /// Does not directly use any hardware intrinsics, nor does it incur branching. + /// + /// The value. + private static int Log2SoftwareFallback(uint value) + { + // No AggressiveInlining due to large method size + // Has conventional contract 0->0 (Log(0) is undefined) + + // Fill trailing zeros with ones, eg 00010010 becomes 00011111 + value |= value >> 01; + value |= value >> 02; + value |= value >> 04; + value |= value >> 08; + value |= value >> 16; + + // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check + return Unsafe.AddByteOffset( + // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_1100_0100_1010_1100_1101_1101u + ref MemoryMarshal.GetReference(Log2DeBruijn), + // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here + (IntPtr)(int)((value * 0x07C4ACDDu) >> 27)); + } + + /// + /// Returns the population count (number of bits set) of a mask. + /// Similar in behavior to the x86 instruction POPCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int PopCount(uint value) + { + const uint c1 = 0x_55555555u; + const uint c2 = 0x_33333333u; + const uint c3 = 0x_0F0F0F0Fu; + const uint c4 = 0x_01010101u; + + value -= (value >> 1) & c1; + value = (value & c2) + ((value >> 2) & c2); + value = (((value + (value >> 4)) & c3) * c4) >> 24; + + return (int)value; + } + + /// + /// Returns the population count (number of bits set) of a mask. + /// Similar in behavior to the x86 instruction POPCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int PopCount(ulong value) + { + if (IntPtr.Size == 4) + { + return PopCount((uint)value) // lo + + PopCount((uint)(value >> 32)); // hi + } + else + { + const ulong c1 = 0x_55555555_55555555ul; + const ulong c2 = 0x_33333333_33333333ul; + const ulong c3 = 0x_0F0F0F0F_0F0F0F0Ful; + const ulong c4 = 0x_01010101_01010101ul; + + value -= (value >> 1) & c1; + value = (value & c2) + ((value >> 2) & c2); + value = (((value + (value >> 4)) & c3) * c4) >> 56; + + return (int)value; + } + } + + /// + /// Count the number of trailing zero bits in an integer value. + /// Similar in behavior to the x86 instruction TZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TrailingZeroCount(int value) + => TrailingZeroCount((uint)value); + + /// + /// Count the number of trailing zero bits in an integer value. + /// Similar in behavior to the x86 instruction TZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TrailingZeroCount(uint value) + { + // Unguarded fallback contract is 0->0 + if (value == 0) + { + return 32; + } + + // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check + return Unsafe.AddByteOffset( + // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_0111_1100_1011_0101_0011_0001u + ref MemoryMarshal.GetReference(TrailingZeroCountDeBruijn), + // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here + (IntPtr)(int)(((value & (uint)-(int)value) * 0x077CB531u) >> 27)); // Multi-cast mitigates redundant conv.u8 + } + + /// + /// Count the number of trailing zero bits in a mask. + /// Similar in behavior to the x86 instruction TZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TrailingZeroCount(long value) + => TrailingZeroCount((ulong)value); + + /// + /// Count the number of trailing zero bits in a mask. + /// Similar in behavior to the x86 instruction TZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TrailingZeroCount(ulong value) + { + uint lo = (uint)value; + + if (lo == 0) + { + return 32 + TrailingZeroCount((uint)(value >> 32)); + } + + return TrailingZeroCount(lo); + } + + /// + /// Rotates the specified value left by the specified number of bits. + /// Similar in behavior to the x86 instruction ROL. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..31] is treated as congruent mod 32. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint RotateLeft(uint value, int offset) + => (value << offset) | (value >> (32 - offset)); + + /// + /// Rotates the specified value left by the specified number of bits. + /// Similar in behavior to the x86 instruction ROL. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..63] is treated as congruent mod 64. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong RotateLeft(ulong value, int offset) + => (value << offset) | (value >> (64 - offset)); + + /// + /// Rotates the specified value right by the specified number of bits. + /// Similar in behavior to the x86 instruction ROR. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..31] is treated as congruent mod 32. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint RotateRight(uint value, int offset) + => (value >> offset) | (value << (32 - offset)); + + /// + /// Rotates the specified value right by the specified number of bits. + /// Similar in behavior to the x86 instruction ROR. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..63] is treated as congruent mod 64. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong RotateRight(ulong value, int offset) + => (value >> offset) | (value << (64 - offset)); + } +} \ No newline at end of file diff --git a/src/ZString/Number/BufferEx.cs b/src/ZString/Number/BufferEx.cs new file mode 100644 index 00000000..0b96bda3 --- /dev/null +++ b/src/ZString/Number/BufferEx.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace System +{ + internal static class BufferEx + { + internal static unsafe void ZeroMemory(byte* dest, uint len) + { + if (len == 0) return; + + for (int i = 0; i < len; i++) + { + dest[i] = 0; + } + } + + internal static unsafe void Memcpy(byte* dest, byte* src, int len) + { + if (len == 0) return; + for (int i = 0; i < len; i++) + { + dest[i] = src[i]; + } + } + } +} diff --git a/src/ZString/Number/DecimalEx.cs b/src/ZString/Number/DecimalEx.cs new file mode 100644 index 00000000..098423fb --- /dev/null +++ b/src/ZString/Number/DecimalEx.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace System +{ + internal static class DecimalEx + { + [StructLayout(LayoutKind.Explicit)] + private struct DecimalBits + { + [FieldOffset(0)] + public int flags; + [FieldOffset(4)] + public int hi; + [FieldOffset(8)] + public int lo; + [FieldOffset(12)] + public int mid; + } + + internal static uint High(this decimal value) + { + return (uint)Unsafe.As(ref value).hi; + } + + internal static uint Low(this decimal value) + { + return (uint)Unsafe.As(ref value).lo; + } + + internal static uint Mid(this decimal value) + { + return (uint)Unsafe.As(ref value).mid; + } + + internal static bool IsNegative(this decimal value) + { + return Unsafe.As(ref value).flags < 0; + } + } +} diff --git a/src/ZString/Number/FloatEx.cs b/src/ZString/Number/FloatEx.cs new file mode 100644 index 00000000..bdc9280f --- /dev/null +++ b/src/ZString/Number/FloatEx.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace System +{ + internal static class FloatEx + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsFinite(double d) + { + long bits = BitConverter.DoubleToInt64Bits(d); + return (bits & 0x7FFFFFFFFFFFFFFF) < 0x7FF0000000000000; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsNegative(double d) + { + return BitConverter.DoubleToInt64Bits(d) < 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsFinite(float f) + { + int bits = SingleToInt32Bits(f); + return (bits & 0x7FFFFFFF) < 0x7F800000; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsNegative(float f) + { + return SingleToInt32Bits(f) < 0; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe int SingleToInt32Bits(float value) + { + return *((int*)&value); + } + } +} diff --git a/src/ZString/Number/InternalSpanEx.cs b/src/ZString/Number/InternalSpanEx.cs new file mode 100644 index 00000000..326bc0c7 --- /dev/null +++ b/src/ZString/Number/InternalSpanEx.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace System +{ + internal static class InternalSpanEx + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool EqualsOrdinalIgnoreCase(this ReadOnlySpan span, ReadOnlySpan value) + { + if (span.Length != value.Length) + return false; + if (value.Length == 0) // span.Length == value.Length == 0 + return true; + + + + return EqualsOrdinalIgnoreCase(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), span.Length); + } + + static bool EqualsOrdinalIgnoreCase(ref char charA, ref char charB, int length) + { + IntPtr byteOffset = IntPtr.Zero; + + if (IntPtr.Size == 8) + { + // Read 4 chars (64 bits) at a time from each string + while ((uint)length >= 4) + { + ulong valueA = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charA, byteOffset))); + ulong valueB = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charB, byteOffset))); + + // A 32-bit test - even with the bit-twiddling here - is more efficient than a 64-bit test. + ulong temp = valueA | valueB; + if (!AllCharsInUInt32AreAscii((uint)temp | (uint)(temp >> 32))) + { + goto NonAscii; // one of the inputs contains non-ASCII data + } + + // Generally, the caller has likely performed a first-pass check that the input strings + // are likely equal. Consider a dictionary which computes the hash code of its key before + // performing a proper deep equality check of the string contents. We want to optimize for + // the case where the equality check is likely to succeed, which means that we want to avoid + // branching within this loop unless we're about to exit the loop, either due to failure or + // due to us running out of input data. + + if (!UInt64OrdinalIgnoreCaseAscii(valueA, valueB)) + { + return false; + } + + byteOffset += 8; + length -= 4; + } + } + + // Read 2 chars (32 bits) at a time from each string + while ((uint)length >= 2) + { + uint valueA = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charA, byteOffset))); + uint valueB = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charB, byteOffset))); + + if (!AllCharsInUInt32AreAscii(valueA | valueB)) + { + goto NonAscii; // one of the inputs contains non-ASCII data + } + + // Generally, the caller has likely performed a first-pass check that the input strings + // are likely equal. Consider a dictionary which computes the hash code of its key before + // performing a proper deep equality check of the string contents. We want to optimize for + // the case where the equality check is likely to succeed, which means that we want to avoid + // branching within this loop unless we're about to exit the loop, either due to failure or + // due to us running out of input data. + + if (!UInt32OrdinalIgnoreCaseAscii(valueA, valueB)) + { + return false; + } + + byteOffset += 4; + length -= 2; + } + + if (length != 0) + { + Debug.Assert(length == 1); + + uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset); + uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset); + + if ((valueA | valueB) > 0x7Fu) + { + goto NonAscii; // one of the inputs contains non-ASCII data + } + + if (valueA == valueB) + { + return true; // exact match + } + + valueA |= 0x20u; + if ((uint)(valueA - 'a') > (uint)('z' - 'a')) + { + return false; // not exact match, and first input isn't in [A-Za-z] + } + + // The ternary operator below seems redundant but helps RyuJIT generate more optimal code. + // See https://github.com/dotnet/coreclr/issues/914. + return (valueA == (valueB | 0x20u)) ? true : false; + } + + Debug.Assert(length == 0); + return true; + + NonAscii: + // The non-ASCII case is factored out into its own helper method so that the JIT + // doesn't need to emit a complex prolog for its caller (this method). + return EqualsOrdinalIgnoreCaseNonAscii(ref Unsafe.AddByteOffset(ref charA, byteOffset), ref Unsafe.AddByteOffset(ref charB, byteOffset), length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool AllCharsInUInt32AreAscii(uint value) + { + return (value & ~0x007F_007Fu) == 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool AllCharsInUInt64AreAscii(ulong value) + { + return (value & ~0x007F_007F_007F_007Ful) == 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool UInt32OrdinalIgnoreCaseAscii(uint valueA, uint valueB) + { + // ASSUMPTION: Caller has validated that input values are ASCII. + Debug.Assert(AllCharsInUInt32AreAscii(valueA)); + Debug.Assert(AllCharsInUInt32AreAscii(valueB)); + + // a mask of all bits which are different between A and B + uint differentBits = valueA ^ valueB; + + // the 0x80 bit of each word of 'lowerIndicator' will be set iff the word has value < 'A' + uint lowerIndicator = valueA + 0x0100_0100u - 0x0041_0041u; + + // the 0x80 bit of each word of 'upperIndicator' will be set iff (word | 0x20) has value > 'z' + uint upperIndicator = (valueA | 0x0020_0020u) + 0x0080_0080u - 0x007B_007Bu; + + // the 0x80 bit of each word of 'combinedIndicator' will be set iff the word is *not* [A-Za-z] + uint combinedIndicator = lowerIndicator | upperIndicator; + + // Shift all the 0x80 bits of 'combinedIndicator' into the 0x20 positions, then set all bits + // aside from 0x20. This creates a mask where all bits are set *except* for the 0x20 bits + // which correspond to alpha chars (either lower or upper). For these alpha chars only, the + // 0x20 bit is allowed to differ between the two input values. Every other char must be an + // exact bitwise match between the two input values. In other words, (valueA & mask) will + // convert valueA to uppercase, so (valueA & mask) == (valueB & mask) answers "is the uppercase + // form of valueA equal to the uppercase form of valueB?" (Technically if valueA has an alpha + // char in the same position as a non-alpha char in valueB, or vice versa, this operation will + // result in nonsense, but it'll still compute as inequal regardless, which is what we want ultimately.) + // The line below is a more efficient way of doing the same check taking advantage of the XOR + // computation we performed at the beginning of the method. + + return (((combinedIndicator >> 2) | ~0x0020_0020u) & differentBits) == 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool UInt64OrdinalIgnoreCaseAscii(ulong valueA, ulong valueB) + { + // ASSUMPTION: Caller has validated that input values are ASCII. + Debug.Assert(AllCharsInUInt64AreAscii(valueA)); + Debug.Assert(AllCharsInUInt64AreAscii(valueB)); + + // the 0x80 bit of each word of 'lowerIndicator' will be set iff the word has value >= 'A' + ulong lowerIndicator = valueA + 0x0080_0080_0080_0080ul - 0x0041_0041_0041_0041ul; + + // the 0x80 bit of each word of 'upperIndicator' will be set iff (word | 0x20) has value <= 'z' + ulong upperIndicator = (valueA | 0x0020_0020_0020_0020ul) + 0x0100_0100_0100_0100ul - 0x007B_007B_007B_007Bul; + + // the 0x20 bit of each word of 'combinedIndicator' will be set iff the word is [A-Za-z] + ulong combinedIndicator = (0x0080_0080_0080_0080ul & lowerIndicator & upperIndicator) >> 2; + + // Convert both values to lowercase (using the combined indicator from the first value) + // and compare for equality. It's possible that the first value will contain an alpha character + // where the second value doesn't (or vice versa), and applying the combined indicator will + // create nonsensical data, but the comparison would have failed anyway in this case so it's + // a safe operation to perform. + // + // This 64-bit method is similar to the 32-bit method, but it performs the equivalent of convert-to- + // lowercase-then-compare rather than convert-to-uppercase-and-compare. This particular operation + // happens to be faster on x64. + + return (valueA | combinedIndicator) == (valueB | combinedIndicator); + } + + private static bool EqualsOrdinalIgnoreCaseNonAscii(ref char charA, ref char charB, int length) + { + //if (!GlobalizationMode.Invariant) + //{ + // return CompareStringOrdinalIgnoreCase(ref charA, length, ref charB, length) == 0; + //} + //else + { + // If we don't have localization tables to consult, we'll still perform a case-insensitive + // check for ASCII characters, but if we see anything outside the ASCII range we'll immediately + // fail if it doesn't have true bitwise equality. + + IntPtr byteOffset = IntPtr.Zero; + while (length != 0) + { + // Ordinal equals or lowercase equals if the result ends up in the a-z range + uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset); + uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset); + + if (valueA == valueB || + ((valueA | 0x20) == (valueB | 0x20) && + (uint)((valueA | 0x20) - 'a') <= (uint)('z' - 'a'))) + { + byteOffset += 2; + length--; + } + else + { + return false; + } + } + + return true; + } + } + } +} diff --git a/src/ZString/Number/MathEx.cs b/src/ZString/Number/MathEx.cs new file mode 100644 index 00000000..c5f93b1d --- /dev/null +++ b/src/ZString/Number/MathEx.cs @@ -0,0 +1,249 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace System +{ + internal static class MathEx + { + internal static uint DivRem(uint a, uint b, out uint result) + { + uint div = a / b; + result = a - (div * b); + return div; + } + + internal static ulong DivRem(ulong a, ulong b, out ulong result) + { + ulong div = a / b; + result = a - (div * b); + return div; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte Clamp(byte value, byte min, byte max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Clamp(decimal value, decimal min, decimal max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Clamp(double value, double min, double max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short Clamp(short value, short min, short max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Clamp(int value, int min, int max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long Clamp(long value, long min, long max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte Clamp(sbyte value, sbyte min, sbyte max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Clamp(float value, float min, float max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort Clamp(ushort value, ushort min, ushort max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Clamp(uint value, uint min, uint max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong Clamp(ulong value, ulong min, ulong max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + private static void ThrowMinMaxException(T min, T max) + { + throw new ArgumentException($"Argument_MinMaxValue, min:{min} max:{max}"); + } + } +} diff --git a/src/ZString/Number/Number.BigInteger.cs b/src/ZString/Number/Number.BigInteger.cs new file mode 100644 index 00000000..686367d0 --- /dev/null +++ b/src/ZString/Number/Number.BigInteger.cs @@ -0,0 +1,1222 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System +{ + internal static partial class Number + { + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal unsafe ref struct BigInteger + { + // The longest binary mantissa requires: explicit mantissa bits + abs(min exponent) + // * Half: 10 + 14 = 24 + // * Single: 23 + 126 = 149 + // * Double: 52 + 1022 = 1074 + // * Quad: 112 + 16382 = 16494 + private const int BitsForLongestBinaryMantissa = 1074; + + // The longest digit sequence requires: ceil(log2(pow(10, max significant digits + 1 rounding digit))) + // * Half: ceil(log2(pow(10, 21 + 1))) = 74 + // * Single: ceil(log2(pow(10, 112 + 1))) = 376 + // * Double: ceil(log2(pow(10, 767 + 1))) = 2552 + // * Quad: ceil(log2(pow(10, 11563 + 1))) = 38415 + private const int BitsForLongestDigitSequence = 2552; + + // We require BitsPerBlock additional bits for shift space used during the pre-division preparation + private const int MaxBits = BitsForLongestBinaryMantissa + BitsForLongestDigitSequence + BitsPerBlock; + + private const int BitsPerBlock = sizeof(int) * 8; + private const int MaxBlockCount = (MaxBits + (BitsPerBlock - 1)) / BitsPerBlock; + + private static readonly uint[] s_Pow10UInt32Table = new uint[] + { + 1, // 10^0 + 10, // 10^1 + 100, // 10^2 + 1000, // 10^3 + 10000, // 10^4 + 100000, // 10^5 + 1000000, // 10^6 + 10000000, // 10^7 + }; + + private static readonly int[] s_Pow10BigNumTableIndices = new int[] + { + 0, // 10^8 + 2, // 10^16 + 5, // 10^32 + 10, // 10^64 + 18, // 10^128 + 33, // 10^256 + 61, // 10^512 + 116, // 10^1024 + }; + + private static readonly uint[] s_Pow10BigNumTable = new uint[] + { + // 10^8 + 1, // _length + 100000000, // _blocks + + // 10^16 + 2, // _length + 0x6FC10000, // _blocks + 0x002386F2, + + // 10^32 + 4, // _length + 0x00000000, // _blocks + 0x85ACEF81, + 0x2D6D415B, + 0x000004EE, + + // 10^64 + 7, // _length + 0x00000000, // _blocks + 0x00000000, + 0xBF6A1F01, + 0x6E38ED64, + 0xDAA797ED, + 0xE93FF9F4, + 0x00184F03, + + // 10^128 + 14, // _length + 0x00000000, // _blocks + 0x00000000, + 0x00000000, + 0x00000000, + 0x2E953E01, + 0x03DF9909, + 0x0F1538FD, + 0x2374E42F, + 0xD3CFF5EC, + 0xC404DC08, + 0xBCCDB0DA, + 0xA6337F19, + 0xE91F2603, + 0x0000024E, + + // 10^256 + 27, // _length + 0x00000000, // _blocks + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x982E7C01, + 0xBED3875B, + 0xD8D99F72, + 0x12152F87, + 0x6BDE50C6, + 0xCF4A6E70, + 0xD595D80F, + 0x26B2716E, + 0xADC666B0, + 0x1D153624, + 0x3C42D35A, + 0x63FF540E, + 0xCC5573C0, + 0x65F9EF17, + 0x55BC28F2, + 0x80DCC7F7, + 0xF46EEDDC, + 0x5FDCEFCE, + 0x000553F7, + + // 10^512 + 54, // _length + 0x00000000, // _blocks + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xFC6CF801, + 0x77F27267, + 0x8F9546DC, + 0x5D96976F, + 0xB83A8A97, + 0xC31E1AD9, + 0x46C40513, + 0x94E65747, + 0xC88976C1, + 0x4475B579, + 0x28F8733B, + 0xAA1DA1BF, + 0x703ED321, + 0x1E25CFEA, + 0xB21A2F22, + 0xBC51FB2E, + 0x96E14F5D, + 0xBFA3EDAC, + 0x329C57AE, + 0xE7FC7153, + 0xC3FC0695, + 0x85A91924, + 0xF95F635E, + 0xB2908EE0, + 0x93ABADE4, + 0x1366732A, + 0x9449775C, + 0x69BE5B0E, + 0x7343AFAC, + 0xB099BC81, + 0x45A71D46, + 0xA2699748, + 0x8CB07303, + 0x8A0B1F13, + 0x8CAB8A97, + 0xC1D238D9, + 0x633415D4, + 0x0000001C, + + // 10^1024 + 107, // _length + 0x00000000, // _blocks + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x2919F001, + 0xF55B2B72, + 0x6E7C215B, + 0x1EC29F86, + 0x991C4E87, + 0x15C51A88, + 0x140AC535, + 0x4C7D1E1A, + 0xCC2CD819, + 0x0ED1440E, + 0x896634EE, + 0x7DE16CFB, + 0x1E43F61F, + 0x9FCE837D, + 0x231D2B9C, + 0x233E55C7, + 0x65DC60D7, + 0xF451218B, + 0x1C5CD134, + 0xC9635986, + 0x922BBB9F, + 0xA7E89431, + 0x9F9F2A07, + 0x62BE695A, + 0x8E1042C4, + 0x045B7A74, + 0x1ABE1DE3, + 0x8AD822A5, + 0xBA34C411, + 0xD814B505, + 0xBF3FDEB3, + 0x8FC51A16, + 0xB1B896BC, + 0xF56DEEEC, + 0x31FB6BFD, + 0xB6F4654B, + 0x101A3616, + 0x6B7595FB, + 0xDC1A47FE, + 0x80D98089, + 0x80BDA5A5, + 0x9A202882, + 0x31EB0F66, + 0xFC8F1F90, + 0x976A3310, + 0xE26A7B7E, + 0xDF68368A, + 0x3CE3A0B8, + 0x8E4262CE, + 0x75A351A2, + 0x6CB0B6C9, + 0x44597583, + 0x31B5653F, + 0xC356E38A, + 0x35FAABA6, + 0x0190FBA0, + 0x9FC4ED52, + 0x88BC491B, + 0x1640114A, + 0x005B8041, + 0xF4F3235E, + 0x1E8D4649, + 0x36A8DE06, + 0x73C55349, + 0xA7E6BD2A, + 0xC1A6970C, + 0x47187094, + 0xD2DB49EF, + 0x926C3F5B, + 0xAE6209D4, + 0x2D433949, + 0x34F4A3C6, + 0xD4305D94, + 0xD9D61A05, + 0x00000325, + + // 9 Trailing blocks to ensure MaxBlockCount + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }; + + private int _length; + private fixed uint _blocks[MaxBlockCount]; + + public static void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result) + { + // determine which operand has the smaller length + ref BigInteger large = ref (lhs._length < rhs._length) ? ref rhs : ref lhs; + ref BigInteger small = ref (lhs._length < rhs._length) ? ref lhs : ref rhs; + + int largeLength = large._length; + int smallLength = small._length; + + // The output will be at least as long as the largest input + result._length = largeLength; + + // Add each block and add carry the overflow to the next block + ulong carry = 0; + + int largeIndex = 0; + int smallIndex = 0; + int resultIndex = 0; + + while (smallIndex < smallLength) + { + ulong sum = carry + large._blocks[largeIndex] + small._blocks[smallIndex]; + carry = sum >> 32; + result._blocks[resultIndex] = (uint)(sum); + + largeIndex++; + smallIndex++; + resultIndex++; + } + + // Add the carry to any blocks that only exist in the large operand + while (largeIndex < largeLength) + { + ulong sum = carry + large._blocks[largeIndex]; + carry = sum >> 32; + result._blocks[resultIndex] = (uint)(sum); + + largeIndex++; + resultIndex++; + } + + // If there's still a carry, append a new block + if (carry != 0) + { + Debug.Assert(carry == 1); + Debug.Assert((resultIndex == largeLength) && (largeLength < MaxBlockCount)); + + result._blocks[resultIndex] = 1; + result._length++; + } + } + + public static int Compare(ref BigInteger lhs, ref BigInteger rhs) + { + Debug.Assert(unchecked((uint)(lhs._length)) <= MaxBlockCount); + Debug.Assert(unchecked((uint)(rhs._length)) <= MaxBlockCount); + + int lhsLength = lhs._length; + int rhsLength = rhs._length; + + int lengthDelta = (lhsLength - rhsLength); + + if (lengthDelta != 0) + { + return lengthDelta; + } + + if (lhsLength == 0) + { + Debug.Assert(rhsLength == 0); + return 0; + } + + for (int index = (lhsLength - 1); index >= 0; index--) + { + long delta = (long)(lhs._blocks[index]) - rhs._blocks[index]; + + if (delta != 0) + { + return delta > 0 ? 1 : -1; + } + } + + return 0; + } + + public static uint CountSignificantBits(uint value) + { + return 32 - (uint)BitOperations.LeadingZeroCount(value); + } + + public static uint CountSignificantBits(ulong value) + { + return 64 - (uint)BitOperations.LeadingZeroCount(value); + } + + public static uint CountSignificantBits(ref BigInteger value) + { + if (value.IsZero()) + { + return 0; + } + + // We don't track any unused blocks, so we only need to do a BSR on the + // last index and add that to the number of bits we skipped. + + uint lastIndex = (uint)(value._length - 1); + return (lastIndex * BitsPerBlock) + CountSignificantBits(value._blocks[lastIndex]); + } + + public static void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger quo, out BigInteger rem) + { + // This is modified from the libraries BigIntegerCalculator.DivRem.cs implementation: + // https://github.com/dotnet/runtime/blob/master/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs + + Debug.Assert(!rhs.IsZero()); + + if (lhs.IsZero()) + { + SetZero(out quo); + SetZero(out rem); + return; + } + + int lhsLength = lhs._length; + int rhsLength = rhs._length; + + if ((lhsLength == 1) && (rhsLength == 1)) + { + uint quotient = MathEx.DivRem(lhs._blocks[0], rhs._blocks[0], out uint remainder); + SetUInt32(out quo, quotient); + SetUInt32(out rem, remainder); + return; + } + + if (rhsLength == 1) + { + // We can make the computation much simpler if the rhs is only one block + + int quoLength = lhsLength; + + ulong rhsValue = rhs._blocks[0]; + ulong carry = 0; + + for (int i = quoLength - 1; i >= 0; i--) + { + ulong value = (carry << 32) | lhs._blocks[i]; + ulong digit = MathEx.DivRem(value, rhsValue, out carry); + + if ((digit == 0) && (i == (quoLength - 1))) + { + quoLength--; + } + else + { + quo._blocks[i] = (uint)(digit); + } + } + + quo._length = quoLength; + SetUInt32(out rem, (uint)(carry)); + + return; + } + else if (rhsLength > lhsLength) + { + // Handle the case where we have no quotient + SetZero(out quo); + SetValue(out rem, ref lhs); + return; + } + else + { + int quoLength = lhsLength - rhsLength + 1; + SetValue(out rem, ref lhs); + int remLength = lhsLength; + + // Executes the "grammar-school" algorithm for computing q = a / b. + // Before calculating q_i, we get more bits into the highest bit + // block of the divisor. Thus, guessing digits of the quotient + // will be more precise. Additionally we'll get r = a % b. + + uint divHi = rhs._blocks[rhsLength - 1]; + uint divLo = rhs._blocks[rhsLength - 2]; + + // We measure the leading zeros of the divisor + int shiftLeft = BitOperations.LeadingZeroCount(divHi); + int shiftRight = 32 - shiftLeft; + + // And, we make sure the most significant bit is set + if (shiftLeft > 0) + { + divHi = (divHi << shiftLeft) | (divLo >> shiftRight); + divLo <<= shiftLeft; + + if (rhsLength > 2) + { + divLo |= (rhs._blocks[rhsLength - 3] >> shiftRight); + } + } + + // Then, we divide all of the bits as we would do it using + // pen and paper: guessing the next digit, subtracting, ... + for (int i = lhsLength; i >= rhsLength; i--) + { + int n = i - rhsLength; + uint t = i < lhsLength ? rem._blocks[i] : 0; + + ulong valHi = ((ulong)(t) << 32) | rem._blocks[i - 1]; + uint valLo = i > 1 ? rem._blocks[i - 2] : 0; + + // We shifted the divisor, we shift the dividend too + if (shiftLeft > 0) + { + valHi = (valHi << shiftLeft) | (valLo >> shiftRight); + valLo <<= shiftLeft; + + if (i > 2) + { + valLo |= (rem._blocks[i - 3] >> shiftRight); + } + } + + // First guess for the current digit of the quotient, + // which naturally must have only 32 bits... + ulong digit = valHi / divHi; + + if (digit > uint.MaxValue) + { + digit = uint.MaxValue; + } + + // Our first guess may be a little bit to big + while (DivideGuessTooBig(digit, valHi, valLo, divHi, divLo)) + { + digit--; + } + + if (digit > 0) + { + // Now it's time to subtract our current quotient + uint carry = SubtractDivisor(ref rem, n, ref rhs, digit); + + if (carry != t) + { + Debug.Assert(carry == t + 1); + + // Our guess was still exactly one too high + carry = AddDivisor(ref rem, n, ref rhs); + digit--; + + Debug.Assert(carry == 1); + } + } + + // We have the digit! + if (quoLength != 0) + { + if ((digit == 0) && (n == (quoLength - 1))) + { + quoLength--; + } + else + { + quo._blocks[n] = (uint)(digit); + } + } + + if (i < remLength) + { + remLength--; + } + } + + quo._length = quoLength; + + // We need to check for the case where remainder is zero + + for (int i = remLength - 1; i >= 0; i--) + { + if (rem._blocks[i] == 0) + { + remLength--; + } + } + + rem._length = remLength; + } + } + + public static uint HeuristicDivide(ref BigInteger dividend, ref BigInteger divisor) + { + int divisorLength = divisor._length; + + if (dividend._length < divisorLength) + { + return 0; + } + + // This is an estimated quotient. Its error should be less than 2. + // Reference inequality: + // a/b - floor(floor(a)/(floor(b) + 1)) < 2 + int lastIndex = (divisorLength - 1); + uint quotient = dividend._blocks[lastIndex] / (divisor._blocks[lastIndex] + 1); + + if (quotient != 0) + { + // Now we use our estimated quotient to update each block of dividend. + // dividend = dividend - divisor * quotient + int index = 0; + + ulong borrow = 0; + ulong carry = 0; + + do + { + ulong product = ((ulong)(divisor._blocks[index]) * quotient) + carry; + carry = product >> 32; + + ulong difference = (ulong)(dividend._blocks[index]) - (uint)(product) - borrow; + borrow = (difference >> 32) & 1; + + dividend._blocks[index] = (uint)(difference); + + index++; + } + while (index < divisorLength); + + // Remove all leading zero blocks from dividend + while ((divisorLength > 0) && (dividend._blocks[divisorLength - 1] == 0)) + { + divisorLength--; + } + + dividend._length = divisorLength; + } + + // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct, + // we increment the quotient and subtract one more divisor from the dividend (Because we guaranteed the error range). + if (Compare(ref dividend, ref divisor) >= 0) + { + quotient++; + + // dividend = dividend - divisor + int index = 0; + ulong borrow = 0; + + do + { + ulong difference = (ulong)(dividend._blocks[index]) - divisor._blocks[index] - borrow; + borrow = (difference >> 32) & 1; + + dividend._blocks[index] = (uint)(difference); + + index++; + } + while (index < divisorLength); + + // Remove all leading zero blocks from dividend + while ((divisorLength > 0) && (dividend._blocks[divisorLength - 1] == 0)) + { + divisorLength--; + } + + dividend._length = divisorLength; + } + + return quotient; + } + + public static void Multiply(ref BigInteger lhs, uint value, out BigInteger result) + { + if (lhs.IsZero() || (value == 1)) + { + SetValue(out result, ref lhs); + return; + } + + if (value == 0) + { + SetZero(out result); + return; + } + + int lhsLength = lhs._length; + int index = 0; + uint carry = 0; + + while (index < lhsLength) + { + ulong product = ((ulong)(lhs._blocks[index]) * value) + carry; + result._blocks[index] = (uint)(product); + carry = (uint)(product >> 32); + + index++; + } + + if (carry != 0) + { + Debug.Assert(unchecked((uint)(lhsLength)) + 1 <= MaxBlockCount); + result._blocks[index] = carry; + result._length = (lhsLength + 1); + } + else + { + result._length = lhsLength; + } + } + + public static void Multiply(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result) + { + if (lhs.IsZero() || rhs.IsOne()) + { + SetValue(out result, ref lhs); + return; + } + + if (rhs.IsZero()) + { + SetZero(out result); + return; + } + + ref readonly BigInteger large = ref lhs; + int largeLength = lhs._length; + + ref readonly BigInteger small = ref rhs; + int smallLength = rhs._length; + + if (largeLength < smallLength) + { + large = ref rhs; + largeLength = rhs._length; + + small = ref lhs; + smallLength = lhs._length; + } + + int maxResultLength = smallLength + largeLength; + Debug.Assert(unchecked((uint)(maxResultLength)) <= MaxBlockCount); + + // Zero out result internal blocks. + result._length = maxResultLength; + BufferEx.ZeroMemory((byte*)result.GetBlocksPointer(), (uint)maxResultLength * sizeof(uint)); + + int smallIndex = 0; + int resultStartIndex = 0; + + while (smallIndex < smallLength) + { + // Multiply each block of large BigNum. + if (small._blocks[smallIndex] != 0) + { + int largeIndex = 0; + int resultIndex = resultStartIndex; + + ulong carry = 0; + + do + { + ulong product = result._blocks[resultIndex] + ((ulong)(small._blocks[smallIndex]) * large._blocks[largeIndex]) + carry; + carry = product >> 32; + result._blocks[resultIndex] = (uint)(product); + + resultIndex++; + largeIndex++; + } + while (largeIndex < largeLength); + + result._blocks[resultIndex] = (uint)(carry); + } + + smallIndex++; + resultStartIndex++; + } + + if ((maxResultLength > 0) && (result._blocks[maxResultLength - 1] == 0)) + { + result._length--; + } + } + + public static void Pow2(uint exponent, out BigInteger result) + { + uint blocksToShift = DivRem32(exponent, out uint remainingBitsToShift); + result._length = (int)blocksToShift + 1; + Debug.Assert(unchecked((uint)result._length) <= MaxBlockCount); + if (blocksToShift > 0) + { + BufferEx.ZeroMemory((byte*)result.GetBlocksPointer(), blocksToShift * sizeof(uint)); + } + result._blocks[blocksToShift] = 1U << (int)(remainingBitsToShift); + } + + public static void Pow10(uint exponent, out BigInteger result) + { + // We leverage two arrays - s_Pow10UInt32Table and s_Pow10BigNumTable to speed up the Pow10 calculation. + // + // s_Pow10UInt32Table stores the results of 10^0 to 10^7. + // s_Pow10BigNumTable stores the results of 10^8, 10^16, 10^32, 10^64, 10^128, 10^256, and 10^512 + // + // For example, let's say exp = 0b111111. We can split the exp to two parts, one is small exp, + // which 10^smallExp can be represented as uint, another part is 10^bigExp, which must be represented as BigNum. + // So the result should be 10^smallExp * 10^bigExp. + // + // Calculating 10^smallExp is simple, we just lookup the 10^smallExp from s_Pow10UInt32Table. + // But here's a bad news: although uint can represent 10^9, exp 9's binary representation is 1001. + // That means 10^(1011), 10^(1101), 10^(1111) all cannot be stored as uint, we cannot easily say something like: + // "Any bits <= 3 is small exp, any bits > 3 is big exp". So instead of involving 10^8, 10^9 to s_Pow10UInt32Table, + // consider 10^8 and 10^9 as a bigNum, so they fall into s_Pow10BigNumTable. Now we can have a simple rule: + // "Any bits <= 3 is small exp, any bits > 3 is big exp". + // + // For 0b111111, we first calculate 10^(smallExp), which is 10^(7), now we can shift right 3 bits, prepare to calculate the bigExp part, + // the exp now becomes 0b000111. + // + // Apparently the lowest bit of bigExp should represent 10^8 because we have already shifted 3 bits for smallExp, so s_Pow10BigNumTable[0] = 10^8. + // Now let's shift exp right 1 bit, the lowest bit should represent 10^(8 * 2) = 10^16, and so on... + // + // That's why we just need the values of s_Pow10BigNumTable be power of 2. + // + // More details of this implementation can be found at: https://github.com/dotnet/coreclr/pull/12894#discussion_r128890596 + + // Validate that `s_Pow10BigNumTable` has exactly enough trailing elements to fill a BigInteger (which contains MaxBlockCount + 1 elements) + // We validate here, since this is the only current consumer of the array + Debug.Assert((s_Pow10BigNumTableIndices[s_Pow10BigNumTableIndices.Length - 1] + MaxBlockCount + 2) == s_Pow10BigNumTable.Length); + + SetUInt32(out BigInteger temp1, s_Pow10UInt32Table[exponent & 0x7]); + ref BigInteger lhs = ref temp1; + + SetZero(out BigInteger temp2); + ref BigInteger product = ref temp2; + + exponent >>= 3; + uint index = 0; + + while (exponent != 0) + { + // If the current bit is set, multiply it with the corresponding power of 10 + if ((exponent & 1) != 0) + { + // Multiply into the next temporary + fixed (uint* pBigNumEntry = &s_Pow10BigNumTable[s_Pow10BigNumTableIndices[index]]) + { + ref BigInteger rhs = ref *(BigInteger*)(pBigNumEntry); + Multiply(ref lhs, ref rhs, out product); + } + + // Swap to the next temporary + ref BigInteger temp = ref product; + product = ref lhs; + lhs = ref temp; + } + + // Advance to the next bit + ++index; + exponent >>= 1; + } + + SetValue(out result, ref lhs); + } + + private static uint AddDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs) + { + int lhsLength = lhs._length; + int rhsLength = rhs._length; + + Debug.Assert(lhsLength >= 0); + Debug.Assert(rhsLength >= 0); + Debug.Assert(lhsLength >= rhsLength); + + // Repairs the dividend, if the last subtract was too much + + ulong carry = 0UL; + + for (int i = 0; i < rhsLength; i++) + { + ref uint lhsValue = ref lhs._blocks[lhsStartIndex + i]; + + ulong digit = lhsValue + carry + rhs._blocks[i]; + lhsValue = unchecked((uint)digit); + carry = digit >> 32; + } + + return (uint)(carry); + } + + private static bool DivideGuessTooBig(ulong q, ulong valHi, uint valLo, uint divHi, uint divLo) + { + Debug.Assert(q <= 0xFFFFFFFF); + + // We multiply the two most significant limbs of the divisor + // with the current guess for the quotient. If those are bigger + // than the three most significant limbs of the current dividend + // we return true, which means the current guess is still too big. + + ulong chkHi = divHi * q; + ulong chkLo = divLo * q; + + chkHi += (chkLo >> 32); + chkLo &= uint.MaxValue; + + if (chkHi < valHi) + return false; + + if (chkHi > valHi) + return true; + + if (chkLo < valLo) + return false; + + if (chkLo > valLo) + return true; + + return false; + } + + private static uint SubtractDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs, ulong q) + { + int lhsLength = lhs._length - lhsStartIndex; + int rhsLength = rhs._length; + + Debug.Assert(lhsLength >= 0); + Debug.Assert(rhsLength >= 0); + Debug.Assert(lhsLength >= rhsLength); + Debug.Assert(q <= uint.MaxValue); + + // Combines a subtract and a multiply operation, which is naturally + // more efficient than multiplying and then subtracting... + + ulong carry = 0; + + for (int i = 0; i < rhsLength; i++) + { + carry += rhs._blocks[i] * q; + uint digit = unchecked((uint)carry); + carry >>= 32; + + ref uint lhsValue = ref lhs._blocks[lhsStartIndex + i]; + + if (lhsValue < digit) + { + carry++; + } + + lhsValue = unchecked(lhsValue - digit); + } + + return (uint)(carry); + } + + public void Add(uint value) + { + int length = _length; + if (length == 0) + { + SetUInt32(out this, value); + return; + } + + _blocks[0] += value; + if (_blocks[0] >= value) + { + // No carry + return; + } + + for (int index = 1; index < length; index++) + { + _blocks[index]++; + if (_blocks[index] > 0) + { + // No carry + return; + } + } + + Debug.Assert(unchecked((uint)(length)) + 1 <= MaxBlockCount); + _blocks[length] = 1; + _length = length + 1; + } + + public uint GetBlock(uint index) + { + Debug.Assert(index < _length); + return _blocks[index]; + } + + public int GetLength() + { + return _length; + } + + public bool IsOne() + { + return (_length == 1) + && (_blocks[0] == 1); + } + + public bool IsZero() + { + return _length == 0; + } + + public void Multiply(uint value) + { + Multiply(ref this, value, out this); + } + + public void Multiply(ref BigInteger value) + { + SetValue(out BigInteger temp, ref this); + Multiply(ref temp, ref value, out this); + } + + public void Multiply10() + { + if (IsZero()) + { + return; + } + + int index = 0; + int length = _length; + ulong carry = 0; + + while (index < length) + { + ulong block = (ulong)(_blocks[index]); + ulong product = (block << 3) + (block << 1) + carry; + carry = product >> 32; + _blocks[index] = (uint)(product); + + index++; + } + + if (carry != 0) + { + Debug.Assert(unchecked((uint)(_length)) + 1 <= MaxBlockCount); + _blocks[index] = (uint)carry; + _length++; + } + } + + public void MultiplyPow10(uint exponent) + { + if (IsZero()) + { + return; + } + + Pow10(exponent, out BigInteger poweredValue); + + if (poweredValue._length == 1) + { + Multiply(poweredValue._blocks[0]); + } + else + { + Multiply(ref poweredValue); + } + } + + public static void SetUInt32(out BigInteger result, uint value) + { + if (value == 0) + { + SetZero(out result); + } + else + { + result._blocks[0] = value; + result._length = 1; + } + } + + public static void SetUInt64(out BigInteger result, ulong value) + { + if (value <= uint.MaxValue) + { + SetUInt32(out result, (uint)(value)); + } + else + { + result._blocks[0] = (uint)(value); + result._blocks[1] = (uint)(value >> 32); + + result._length = 2; + } + } + + public static void SetValue(out BigInteger result, ref BigInteger value) + { + int rhsLength = value._length; + result._length = rhsLength; + BufferEx.Memcpy((byte*)result.GetBlocksPointer(), (byte*)value.GetBlocksPointer(), rhsLength * sizeof(uint)); + } + + public static void SetZero(out BigInteger result) + { + result._length = 0; + } + + public void ShiftLeft(uint shift) + { + // Process blocks high to low so that we can safely process in place + int length = _length; + + if ((length == 0) || (shift == 0)) + { + return; + } + + uint blocksToShift = DivRem32(shift, out uint remainingBitsToShift); + + // Copy blocks from high to low + int readIndex = (length - 1); + int writeIndex = readIndex + (int)(blocksToShift); + + // Check if the shift is block aligned + if (remainingBitsToShift == 0) + { + Debug.Assert(writeIndex < MaxBlockCount); + + while (readIndex >= 0) + { + _blocks[writeIndex] = _blocks[readIndex]; + readIndex--; + writeIndex--; + } + + _length += (int)(blocksToShift); + + // Zero the remaining low blocks + BufferEx.ZeroMemory((byte*)GetBlocksPointer(), blocksToShift * sizeof(uint)); + } + else + { + // We need an extra block for the partial shift + writeIndex++; + Debug.Assert(writeIndex < MaxBlockCount); + + // Set the length to hold the shifted blocks + _length = writeIndex + 1; + + // Output the initial blocks + uint lowBitsShift = (32 - remainingBitsToShift); + uint highBits = 0; + uint block = _blocks[readIndex]; + uint lowBits = block >> (int)(lowBitsShift); + while (readIndex > 0) + { + _blocks[writeIndex] = highBits | lowBits; + highBits = block << (int)(remainingBitsToShift); + + --readIndex; + --writeIndex; + + block = _blocks[readIndex]; + lowBits = block >> (int)lowBitsShift; + } + + // Output the final blocks + _blocks[writeIndex] = highBits | lowBits; + _blocks[writeIndex - 1] = block << (int)(remainingBitsToShift); + + // Zero the remaining low blocks + BufferEx.ZeroMemory((byte*)GetBlocksPointer(), blocksToShift * sizeof(uint)); + + // Check if the terminating block has no set bits + if (_blocks[_length - 1] == 0) + { + _length--; + } + } + } + + public ulong ToUInt64() + { + if (_length > 1) + { + return ((ulong)(_blocks[1]) << 32) + _blocks[0]; + } + + if (_length > 0) + { + return _blocks[0]; + } + + return 0; + } + + private uint* GetBlocksPointer() + { + // This is safe to do since we are a ref struct + return (uint*)(Unsafe.AsPointer(ref _blocks[0])); + } + + private static uint DivRem32(uint value, out uint remainder) + { + remainder = value & 31; + return value >> 5; + } + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/Number.DiyFp.cs b/src/ZString/Number/Number.DiyFp.cs new file mode 100644 index 00000000..562dd9a1 --- /dev/null +++ b/src/ZString/Number/Number.DiyFp.cs @@ -0,0 +1,157 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Numerics; + +namespace System +{ + internal static partial class Number + { + // This is a port of the `DiyFp` implementation here: https://github.com/google/double-conversion/blob/a711666ddd063eb1e4b181a6cb981d39a1fc8bac/double-conversion/diy-fp.h + // The backing structure and how it is used is described in more detail here: http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf + + // This "Do It Yourself Floating Point" class implements a floating-point number with a ulong significand and an int exponent. + // Normalized DiyFp numbers will have the most significant bit of the significand set. + // Multiplication and Subtraction do not normalize their results. + // DiyFp are not designed to contain special doubles (NaN and Infinity). + internal readonly ref struct DiyFp + { + public const int DoubleImplicitBitIndex = 52; + public const int SingleImplicitBitIndex = 23; + + public const int SignificandSize = 64; + + public readonly ulong f; + public readonly int e; + + // Computes the two boundaries of value. + // + // The bigger boundary (mPlus) is normalized. + // The lower boundary has the same exponent as mPlus. + // + // Precondition: + // The value encoded by value must be greater than 0. + public static DiyFp CreateAndGetBoundaries(double value, out DiyFp mMinus, out DiyFp mPlus) + { + var result = new DiyFp(value); + result.GetBoundaries(DoubleImplicitBitIndex, out mMinus, out mPlus); + return result; + } + + // Computes the two boundaries of value. + // + // The bigger boundary (mPlus) is normalized. + // The lower boundary has the same exponent as mPlus. + // + // Precondition: + // The value encoded by value must be greater than 0. + public static DiyFp CreateAndGetBoundaries(float value, out DiyFp mMinus, out DiyFp mPlus) + { + var result = new DiyFp(value); + result.GetBoundaries(SingleImplicitBitIndex, out mMinus, out mPlus); + return result; + } + + public DiyFp(double value) + { + //Debug.Assert(double.IsFinite(value)); + Debug.Assert(value > 0.0); + f = ExtractFractionAndBiasedExponent(value, out e); + } + + public DiyFp(float value) + { + //Debug.Assert(float.IsFinite(value)); + Debug.Assert(value > 0.0f); + f = ExtractFractionAndBiasedExponent(value, out e); + } + + public DiyFp(ulong f, int e) + { + this.f = f; + this.e = e; + } + + public DiyFp Multiply(in DiyFp other) + { + // Simply "emulates" a 128-bit multiplication + // + // However: the resulting number only contains 64-bits. The least + // signficant 64-bits are only used for rounding the most significant + // 64-bits. + + uint a = (uint)(f >> 32); + uint b = (uint)(f); + + uint c = (uint)(other.f >> 32); + uint d = (uint)(other.f); + + ulong ac = ((ulong)(a) * c); + ulong bc = ((ulong)(b) * c); + ulong ad = ((ulong)(a) * d); + ulong bd = ((ulong)(b) * d); + + ulong tmp = (bd >> 32) + (uint)(ad) + (uint)(bc); + + // By adding (1UL << 31) to tmp, we round the final result. + // Halfway cases will be rounded up. + + tmp += (1U << 31); + + return new DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + other.e + SignificandSize); + } + + public DiyFp Normalize() + { + // This method is mainly called for normalizing boundaries. + // + // We deviate from the reference implementation by just using + // our LeadingZeroCount function so that we only need to shift + // and subtract once. + + Debug.Assert(f != 0); + int lzcnt = BitOperations.LeadingZeroCount(f); + return new DiyFp(f << lzcnt, e - lzcnt); + } + + // The exponents of both numbers must be the same. + // The significand of 'this' must be bigger than the significand of 'other'. + // The result will not be normalized. + public DiyFp Subtract(in DiyFp other) + { + Debug.Assert(e == other.e); + Debug.Assert(f >= other.f); + return new DiyFp(f - other.f, e); + } + + private void GetBoundaries(int implicitBitIndex, out DiyFp mMinus, out DiyFp mPlus) + { + mPlus = new DiyFp((f << 1) + 1, e - 1).Normalize(); + + // The boundary is closer if the sigificand is of the form: + // f == 2^p-1 + // + // Think of v = 1000e10 and v- = 9999e9 + // Then the boundary == (v - v-) / 2 is not just at a distance of 1e9 but at a distance of 1e8. + // The only exception is for the smallest normal, where the largest denormal is at the same distance as its successor. + // + // Note: denormals have the same exponent as the smallest normals. + + // We deviate from the reference implementation by just checking if the significand has only the implicit bit set. + // In this scenario, we know that all the explicit bits are 0 and that the unbiased exponent is non-zero. + if (f == (1UL << implicitBitIndex)) + { + mMinus = new DiyFp((f << 2) - 1, e - 2); + } + else + { + mMinus = new DiyFp((f << 1) - 1, e - 1); + } + + mMinus = new DiyFp(mMinus.f << (mMinus.e - mPlus.e), mPlus.e); + } + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/Number.Dragon4.cs b/src/ZString/Number/Number.Dragon4.cs new file mode 100644 index 00000000..4831987f --- /dev/null +++ b/src/ZString/Number/Number.Dragon4.cs @@ -0,0 +1,525 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System +{ + // This is a port of the `Dragon4` implementation here: http://www.ryanjuckett.com/programming/printing-floating-point-numbers/part-2/ + // The backing algorithm and the proofs behind it are described in more detail here: https://www.cs.indiana.edu/~dyb/pubs/FP-Printing-PLDI96.pdf + internal static partial class Number + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe bool IsNegative(double d) + { + return BitConverter.DoubleToInt64Bits(d) < 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsNegativeInfinity(float f) + { + return f == float.NegativeInfinity; + } + + public static void Dragon4Double(double value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number) + { + double v = IsNegative(value) ? -value : value; + + Debug.Assert(v > 0); + // Debug.Assert(double.IsFinite(v)); + + ulong mantissa = ExtractFractionAndBiasedExponent(value, out int exponent); + + uint mantissaHighBitIdx; + bool hasUnequalMargins = false; + + if ((mantissa >> DiyFp.DoubleImplicitBitIndex) != 0) + { + mantissaHighBitIdx = DiyFp.DoubleImplicitBitIndex; + hasUnequalMargins = (mantissa == (1UL << DiyFp.DoubleImplicitBitIndex)); + } + else + { + Debug.Assert(mantissa != 0); + mantissaHighBitIdx = (uint)BitOperations.Log2(mantissa); + } + + int length = (int)(Dragon4(mantissa, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out int decimalExponent)); + + number.Scale = decimalExponent + 1; + number.Digits[length] = (byte)('\0'); + number.DigitsCount = length; + } + + public static unsafe void Dragon4Single(float value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number) + { + float v = IsNegative(value) ? -value : value; + + Debug.Assert(v > 0); + // Debug.Assert(float.IsFinite(v)); + + uint mantissa = ExtractFractionAndBiasedExponent(value, out int exponent); + + uint mantissaHighBitIdx; + bool hasUnequalMargins = false; + + if ((mantissa >> DiyFp.SingleImplicitBitIndex) != 0) + { + mantissaHighBitIdx = DiyFp.SingleImplicitBitIndex; + hasUnequalMargins = (mantissa == (1U << DiyFp.SingleImplicitBitIndex)); + } + else + { + Debug.Assert(mantissa != 0); + mantissaHighBitIdx = (uint)BitOperations.Log2(mantissa); + } + + int length = (int)(Dragon4(mantissa, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out int decimalExponent)); + + number.Scale = decimalExponent + 1; + number.Digits[length] = (byte)('\0'); + number.DigitsCount = length; + } + + // This is an implementation of the Dragon4 algorithm to convert a binary number in floating-point format to a decimal number in string format. + // The function returns the number of digits written to the output buffer and the output is not NUL terminated. + // + // The floating point input value is (mantissa * 2^exponent). + // + // See the following papers for more information on the algorithm: + // "How to Print Floating-Point Numbers Accurately" + // Steele and White + // http://kurtstephens.com/files/p372-steele.pdf + // "Printing Floating-Point Numbers Quickly and Accurately" + // Burger and Dybvig + // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf + private static unsafe uint Dragon4(ulong mantissa, int exponent, uint mantissaHighBitIdx, bool hasUnequalMargins, int cutoffNumber, bool isSignificantDigits, Span buffer, out int decimalExponent) + { + int curDigit = 0; + + Debug.Assert(buffer.Length > 0); + + // We deviate from the original algorithm and just assert that the mantissa + // is not zero. Comparing to zero is fine since the caller should have set + // the implicit bit of the mantissa, meaning it would only ever be zero if + // the extracted exponent was also zero. And the assertion is fine since we + // require that the DoubleToNumber handle zero itself. + Debug.Assert(mantissa != 0); + + // Compute the initial state in integral form such that + // value = scaledValue / scale + // marginLow = scaledMarginLow / scale + + BigInteger scale; // positive scale applied to value and margin such that they can be represented as whole numbers + BigInteger scaledValue; // scale * mantissa + BigInteger scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its immediate lower value) + + // For normalized IEEE floating-point values, each time the exponent is incremented the margin also doubles. + // That creates a subset of transition numbers where the high margin is twice the size of the low margin. + BigInteger* pScaledMarginHigh; + BigInteger optionalMarginHigh; + + if (hasUnequalMargins) + { + if (exponent > 0) // We have no fractional component + { + // 1) Expand the input value by multiplying out the mantissa and exponent. + // This represents the input value in its whole number representation. + // 2) Apply an additional scale of 2 such that later comparisons against the margin values are simplified. + // 3) Set the margin value to the loweset mantissa bit's scale. + + // scaledValue = 2 * 2 * mantissa * 2^exponent + BigInteger.SetUInt64(out scaledValue, 4 * mantissa); + scaledValue.ShiftLeft((uint)(exponent)); + + // scale = 2 * 2 * 1 + BigInteger.SetUInt32(out scale, 4); + + // scaledMarginLow = 2 * 2^(exponent - 1) + BigInteger.Pow2((uint)(exponent), out scaledMarginLow); + + // scaledMarginHigh = 2 * 2 * 2^(exponent + 1) + BigInteger.Pow2((uint)(exponent + 1), out optionalMarginHigh); + } + else // We have a fractional exponent + { + // In order to track the mantissa data as an integer, we store it as is with a large scale + + // scaledValue = 2 * 2 * mantissa + BigInteger.SetUInt64(out scaledValue, 4 * mantissa); + + // scale = 2 * 2 * 2^(-exponent) + BigInteger.Pow2((uint)(-exponent + 2), out scale); + + // scaledMarginLow = 2 * 2^(-1) + BigInteger.SetUInt32(out scaledMarginLow, 1); + + // scaledMarginHigh = 2 * 2 * 2^(-1) + BigInteger.SetUInt32(out optionalMarginHigh, 2); + } + + // The high and low margins are different + pScaledMarginHigh = &optionalMarginHigh; + } + else + { + if (exponent > 0) // We have no fractional component + { + // 1) Expand the input value by multiplying out the mantissa and exponent. + // This represents the input value in its whole number representation. + // 2) Apply an additional scale of 2 such that later comparisons against the margin values are simplified. + // 3) Set the margin value to the lowest mantissa bit's scale. + + // scaledValue = 2 * mantissa*2^exponent + BigInteger.SetUInt64(out scaledValue, 2 * mantissa); + scaledValue.ShiftLeft((uint)(exponent)); + + // scale = 2 * 1 + BigInteger.SetUInt32(out scale, 2); + + // scaledMarginLow = 2 * 2^(exponent-1) + BigInteger.Pow2((uint)(exponent), out scaledMarginLow); + } + else // We have a fractional exponent + { + // In order to track the mantissa data as an integer, we store it as is with a large scale + + // scaledValue = 2 * mantissa + BigInteger.SetUInt64(out scaledValue, 2 * mantissa); + + // scale = 2 * 2^(-exponent) + BigInteger.Pow2((uint)(-exponent + 1), out scale); + + // scaledMarginLow = 2 * 2^(-1) + BigInteger.SetUInt32(out scaledMarginLow, 1); + } + + // The high and low margins are equal + pScaledMarginHigh = &scaledMarginLow; + } + + // Compute an estimate for digitExponent that will be correct or undershoot by one. + // + // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately" by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf + // + // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate because that lets us take a faster branch in the code. + // 0.69 is chosen because 0.69 + log10(2) is less than one by a reasonable epsilon that will account for any floating point error. + // + // We want to set digitExponent to floor(log10(v)) + 1 + // v = mantissa * 2^exponent + // log2(v) = log2(mantissa) + exponent; + // log10(v) = log2(v) * log10(2) + // floor(log2(v)) = mantissaHighBitIdx + exponent; + // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v) + // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2) + // floor(log10(v)) < ceil((mantissaHighBitIdx + exponent) * log10(2)) <= floor(log10(v)) + 1 + const double Log10V2 = 0.30102999566398119521373889472449; + int digitExponent = (int)(Math.Ceiling(((int)(mantissaHighBitIdx) + exponent) * Log10V2 - 0.69)); + + // Divide value by 10^digitExponent. + if (digitExponent > 0) + { + // The exponent is positive creating a division so we multiply up the scale. + scale.MultiplyPow10((uint)(digitExponent)); + } + else if (digitExponent < 0) + { + // The exponent is negative creating a multiplication so we multiply up the scaledValue, scaledMarginLow and scaledMarginHigh. + + BigInteger.Pow10((uint)(-digitExponent), out BigInteger pow10); + + scaledValue.Multiply(ref pow10); + scaledMarginLow.Multiply(ref pow10); + + if (pScaledMarginHigh != &scaledMarginLow) + { + BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); + } + } + + bool isEven = (mantissa % 2) == 0; + bool estimateTooLow = false; + + if (cutoffNumber == -1) + { + // When printing the shortest possible string, we want to + // take IEEE unbiased rounding into account so we can return + // shorter strings for various edge case values like 1.23E+22 + + BigInteger.Add(ref scaledValue, ref *pScaledMarginHigh, out BigInteger scaledValueHigh); + int cmpHigh = BigInteger.Compare(ref scaledValueHigh, ref scale); + estimateTooLow = isEven ? (cmpHigh >= 0) : (cmpHigh > 0); + } + else + { + estimateTooLow = BigInteger.Compare(ref scaledValue, ref scale) >= 0; + } + + // Was our estimate for digitExponent was too low? + if (estimateTooLow) + { + // The exponent estimate was incorrect. + // Increment the exponent and don't perform the premultiply needed for the first loop iteration. + digitExponent++; + } + else + { + // The exponent estimate was correct. + // Multiply larger by the output base to prepare for the first loop iteration. + scaledValue.Multiply10(); + scaledMarginLow.Multiply10(); + + if (pScaledMarginHigh != &scaledMarginLow) + { + BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); + } + } + + // Compute the cutoff exponent (the exponent of the final digit to print). + // Default to the maximum size of the output buffer. + int cutoffExponent = digitExponent - buffer.Length; + + if (cutoffNumber != -1) + { + int desiredCutoffExponent = 0; + + if (isSignificantDigits) + { + // We asked for a specific number of significant digits. + Debug.Assert(cutoffNumber > 0); + desiredCutoffExponent = digitExponent - cutoffNumber; + } + else + { + // We asked for a specific number of fractional digits. + Debug.Assert(cutoffNumber >= 0); + desiredCutoffExponent = -cutoffNumber; + } + + if (desiredCutoffExponent > cutoffExponent) + { + // Only select the new cutoffExponent if it won't overflow the destination buffer. + cutoffExponent = desiredCutoffExponent; + } + } + + // Output the exponent of the first digit we will print + decimalExponent = --digitExponent; + + // In preparation for calling BigInteger.HeuristicDivie(), we need to scale up our values such that the highest block of the denominator is greater than or equal to 8. + // We also need to guarantee that the numerator can never have a length greater than the denominator after each loop iteration. + // This requires the highest block of the denominator to be less than or equal to 429496729 which is the highest number that can be multiplied by 10 without overflowing to a new block. + + Debug.Assert(scale.GetLength() > 0); + uint hiBlock = scale.GetBlock((uint)(scale.GetLength() - 1)); + + if ((hiBlock < 8) || (hiBlock > 429496729)) + { + // Perform a bit shift on all values to get the highest block of the denominator into the range [8,429496729]. + // We are more likely to make accurate quotient estimations in BigInteger.HeuristicDivide() with higher denominator values so we shift the denominator to place the highest bit at index 27 of the highest block. + // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. + // This means that all values with a highest bit at index 27 are within range. + Debug.Assert(hiBlock != 0); + uint hiBlockLog2 = (uint)BitOperations.Log2(hiBlock); + Debug.Assert((hiBlockLog2 < 3) || (hiBlockLog2 > 27)); + uint shift = (32 + 27 - hiBlockLog2) % 32; + + scale.ShiftLeft(shift); + scaledValue.ShiftLeft(shift); + scaledMarginLow.ShiftLeft(shift); + + if (pScaledMarginHigh != &scaledMarginLow) + { + BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); + } + } + + // These values are used to inspect why the print loop terminated so we can properly round the final digit. + bool low; // did the value get within marginLow distance from zero + bool high; // did the value get within marginHigh distance from one + uint outputDigit; // current digit being output + + if (cutoffNumber == -1) + { + Debug.Assert(isSignificantDigits); + Debug.Assert(digitExponent >= cutoffExponent); + + // For the unique cutoff mode, we will try to print until we have reached a level of precision that uniquely distinguishes this value from its neighbors. + // If we run out of space in the output buffer, we terminate early. + + while (true) + { + // divide out the scale to extract the digit + outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); + Debug.Assert(outputDigit < 10); + + // update the high end of the value + BigInteger.Add(ref scaledValue, ref *pScaledMarginHigh, out BigInteger scaledValueHigh); + + // stop looping if we are far enough away from our neighboring values or if we have reached the cutoff digit + int cmpLow = BigInteger.Compare(ref scaledValue, ref scaledMarginLow); + int cmpHigh = BigInteger.Compare(ref scaledValueHigh, ref scale); + + if (isEven) + { + low = (cmpLow <= 0); + high = (cmpHigh >= 0); + } + else + { + low = (cmpLow < 0); + high = (cmpHigh > 0); + } + + if (low || high || (digitExponent == cutoffExponent)) + { + break; + } + + // store the output digit + buffer[curDigit] = (byte)('0' + outputDigit); + curDigit++; + + // multiply larger by the output base + scaledValue.Multiply10(); + scaledMarginLow.Multiply10(); + + if (pScaledMarginHigh != &scaledMarginLow) + { + BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); + } + + digitExponent--; + } + } + else if (digitExponent >= cutoffExponent) + { + Debug.Assert((cutoffNumber > 0) || ((cutoffNumber == 0) && !isSignificantDigits)); + + // For length based cutoff modes, we will try to print until we have exhausted all precision (i.e. all remaining digits are zeros) or until we reach the desired cutoff digit. + low = false; + high = false; + + while (true) + { + // divide out the scale to extract the digit + outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); + Debug.Assert(outputDigit < 10); + + if (scaledValue.IsZero() || (digitExponent <= cutoffExponent)) + { + break; + } + + // store the output digit + buffer[curDigit] = (byte)('0' + outputDigit); + curDigit++; + + // multiply larger by the output base + scaledValue.Multiply10(); + digitExponent--; + } + } + else + { + // In the scenario where the first significant digit is after the cutoff, we want to treat that + // first significant digit as the rounding digit. If the first significant would cause the next + // digit to round, we will increase the decimalExponent by one and set the previous digit to one. + // This ensures we correctly handle the case where the first significant digit is exactly one after + // the cutoff, it is a 4, and the subsequent digit would round that to 5 inducing a double rounding + // bug when NumberToString does its own rounding checks. However, if the first significant digit + // would not cause the next one to round, we preserve that digit as is. + + // divide out the scale to extract the digit + outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); + Debug.Assert((0 < outputDigit) && (outputDigit < 10)); + + if ((outputDigit > 5) || ((outputDigit == 5) && !scaledValue.IsZero())) + { + decimalExponent++; + outputDigit = 1; + } + + buffer[curDigit] = (byte)('0' + outputDigit); + curDigit++; + + // return the number of digits output + return (uint)curDigit; + } + + // round off the final digit + // default to rounding down if value got too close to 0 + bool roundDown = low; + + if (low == high) // is it legal to round up and down + { + // round to the closest digit by comparing value with 0.5. + // + // To do this we need to convert the inequality to large integer values. + // compare(value, 0.5) + // compare(scale * value, scale * 0.5) + // compare(2 * scale * value, scale) + scaledValue.ShiftLeft(1); // Multiply by 2 + int compare = BigInteger.Compare(ref scaledValue, ref scale); + roundDown = compare < 0; + + // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules) + if (compare == 0) + { + roundDown = (outputDigit & 1) == 0; + } + } + + // print the rounded digit + if (roundDown) + { + buffer[curDigit] = (byte)('0' + outputDigit); + curDigit++; + } + else if (outputDigit == 9) // handle rounding up + { + // find the first non-nine prior digit + while (true) + { + // if we are at the first digit + if (curDigit == 0) + { + // output 1 at the next highest exponent + + buffer[curDigit] = (byte)('1'); + curDigit++; + decimalExponent++; + + break; + } + + curDigit--; + + if (buffer[curDigit] != '9') + { + // increment the digit + + buffer[curDigit]++; + curDigit++; + + break; + } + } + } + else + { + // values in the range [0,8] can perform a simple round up + buffer[curDigit] = (byte)('0' + outputDigit + 1); + curDigit++; + } + + // return the number of digits output + uint outputLen = (uint)curDigit; + Debug.Assert(outputLen <= buffer.Length); + return outputLen; + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/Number.Formatting.cs b/src/ZString/Number/Number.Formatting.cs new file mode 100644 index 00000000..a7bda20a --- /dev/null +++ b/src/ZString/Number/Number.Formatting.cs @@ -0,0 +1,2539 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Buffers.Text; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace System +{ + // The Format methods provided by the numeric classes convert + // the numeric value to a string using the format string given by the + // format parameter. If the format parameter is null or + // an empty string, the number is formatted as if the string "G" (general + // format) was specified. The info parameter specifies the + // NumberFormatInfo instance to use when formatting the number. If the + // info parameter is null or omitted, the numeric formatting information + // is obtained from the current culture. The NumberFormatInfo supplies + // such information as the characters to use for decimal and thousand + // separators, and the spelling and placement of currency symbols in monetary + // values. + // + // Format strings fall into two categories: Standard format strings and + // user-defined format strings. A format string consisting of a single + // alphabetic character (A-Z or a-z), optionally followed by a sequence of + // digits (0-9), is a standard format string. All other format strings are + // used-defined format strings. + // + // A standard format string takes the form Axx, where A is an + // alphabetic character called the format specifier and xx is a + // sequence of digits called the precision specifier. The format + // specifier controls the type of formatting applied to the number and the + // precision specifier controls the number of significant digits or decimal + // places of the formatting operation. The following table describes the + // supported standard formats. + // + // C c - Currency format. The number is + // converted to a string that represents a currency amount. The conversion is + // controlled by the currency format information of the NumberFormatInfo + // used to format the number. The precision specifier indicates the desired + // number of decimal places. If the precision specifier is omitted, the default + // currency precision given by the NumberFormatInfo is used. + // + // D d - Decimal format. This format is + // supported for integral types only. The number is converted to a string of + // decimal digits, prefixed by a minus sign if the number is negative. The + // precision specifier indicates the minimum number of digits desired in the + // resulting string. If required, the number will be left-padded with zeros to + // produce the number of digits given by the precision specifier. + // + // E e Engineering (scientific) format. + // The number is converted to a string of the form + // "-d.ddd...E+ddd" or "-d.ddd...e+ddd", where each + // 'd' indicates a digit (0-9). The string starts with a minus sign if the + // number is negative, and one digit always precedes the decimal point. The + // precision specifier indicates the desired number of digits after the decimal + // point. If the precision specifier is omitted, a default of 6 digits after + // the decimal point is used. The format specifier indicates whether to prefix + // the exponent with an 'E' or an 'e'. The exponent is always consists of a + // plus or minus sign and three digits. + // + // F f Fixed point format. The number is + // converted to a string of the form "-ddd.ddd....", where each + // 'd' indicates a digit (0-9). The string starts with a minus sign if the + // number is negative. The precision specifier indicates the desired number of + // decimal places. If the precision specifier is omitted, the default numeric + // precision given by the NumberFormatInfo is used. + // + // G g - General format. The number is + // converted to the shortest possible decimal representation using fixed point + // or scientific format. The precision specifier determines the number of + // significant digits in the resulting string. If the precision specifier is + // omitted, the number of significant digits is determined by the type of the + // number being converted (10 for int, 19 for long, 7 for + // float, 15 for double, 19 for Currency, and 29 for + // Decimal). Trailing zeros after the decimal point are removed, and the + // resulting string contains a decimal point only if required. The resulting + // string uses fixed point format if the exponent of the number is less than + // the number of significant digits and greater than or equal to -4. Otherwise, + // the resulting string uses scientific format, and the case of the format + // specifier controls whether the exponent is prefixed with an 'E' or an 'e'. + // + // N n Number format. The number is + // converted to a string of the form "-d,ddd,ddd.ddd....", where + // each 'd' indicates a digit (0-9). The string starts with a minus sign if the + // number is negative. Thousand separators are inserted between each group of + // three digits to the left of the decimal point. The precision specifier + // indicates the desired number of decimal places. If the precision specifier + // is omitted, the default numeric precision given by the + // NumberFormatInfo is used. + // + // X x - Hexadecimal format. This format is + // supported for integral types only. The number is converted to a string of + // hexadecimal digits. The format specifier indicates whether to use upper or + // lower case characters for the hexadecimal digits above 9 ('X' for 'ABCDEF', + // and 'x' for 'abcdef'). The precision specifier indicates the minimum number + // of digits desired in the resulting string. If required, the number will be + // left-padded with zeros to produce the number of digits given by the + // precision specifier. + // + // Some examples of standard format strings and their results are shown in the + // table below. (The examples all assume a default NumberFormatInfo.) + // + // Value Format Result + // 12345.6789 C $12,345.68 + // -12345.6789 C ($12,345.68) + // 12345 D 12345 + // 12345 D8 00012345 + // 12345.6789 E 1.234568E+004 + // 12345.6789 E10 1.2345678900E+004 + // 12345.6789 e4 1.2346e+004 + // 12345.6789 F 12345.68 + // 12345.6789 F0 12346 + // 12345.6789 F6 12345.678900 + // 12345.6789 G 12345.6789 + // 12345.6789 G7 12345.68 + // 123456789 G7 1.234568E8 + // 12345.6789 N 12,345.68 + // 123456789 N4 123,456,789.0000 + // 0x2c45e x 2c45e + // 0x2c45e X 2C45E + // 0x2c45e X8 0002C45E + // + // Format strings that do not start with an alphabetic character, or that start + // with an alphabetic character followed by a non-digit, are called + // user-defined format strings. The following table describes the formatting + // characters that are supported in user defined format strings. + // + // + // 0 - Digit placeholder. If the value being + // formatted has a digit in the position where the '0' appears in the format + // string, then that digit is copied to the output string. Otherwise, a '0' is + // stored in that position in the output string. The position of the leftmost + // '0' before the decimal point and the rightmost '0' after the decimal point + // determines the range of digits that are always present in the output + // string. + // + // # - Digit placeholder. If the value being + // formatted has a digit in the position where the '#' appears in the format + // string, then that digit is copied to the output string. Otherwise, nothing + // is stored in that position in the output string. + // + // . - Decimal point. The first '.' character + // in the format string determines the location of the decimal separator in the + // formatted value; any additional '.' characters are ignored. The actual + // character used as a the decimal separator in the output string is given by + // the NumberFormatInfo used to format the number. + // + // , - Thousand separator and number scaling. + // The ',' character serves two purposes. First, if the format string contains + // a ',' character between two digit placeholders (0 or #) and to the left of + // the decimal point if one is present, then the output will have thousand + // separators inserted between each group of three digits to the left of the + // decimal separator. The actual character used as a the decimal separator in + // the output string is given by the NumberFormatInfo used to format the + // number. Second, if the format string contains one or more ',' characters + // immediately to the left of the decimal point, or after the last digit + // placeholder if there is no decimal point, then the number will be divided by + // 1000 times the number of ',' characters before it is formatted. For example, + // the format string '0,,' will represent 100 million as just 100. Use of the + // ',' character to indicate scaling does not also cause the formatted number + // to have thousand separators. Thus, to scale a number by 1 million and insert + // thousand separators you would use the format string '#,##0,,'. + // + // % - Percentage placeholder. The presence of + // a '%' character in the format string causes the number to be multiplied by + // 100 before it is formatted. The '%' character itself is inserted in the + // output string where it appears in the format string. + // + // E+ E- e+ e- - Scientific notation. + // If any of the strings 'E+', 'E-', 'e+', or 'e-' are present in the format + // string and are immediately followed by at least one '0' character, then the + // number is formatted using scientific notation with an 'E' or 'e' inserted + // between the number and the exponent. The number of '0' characters following + // the scientific notation indicator determines the minimum number of digits to + // output for the exponent. The 'E+' and 'e+' formats indicate that a sign + // character (plus or minus) should always precede the exponent. The 'E-' and + // 'e-' formats indicate that a sign character should only precede negative + // exponents. + // + // \ - Literal character. A backslash character + // causes the next character in the format string to be copied to the output + // string as-is. The backslash itself isn't copied, so to place a backslash + // character in the output string, use two backslashes (\\) in the format + // string. + // + // 'ABC' "ABC" - Literal string. Characters + // enclosed in single or double quotation marks are copied to the output string + // as-is and do not affect formatting. + // + // ; - Section separator. The ';' character is + // used to separate sections for positive, negative, and zero numbers in the + // format string. + // + // Other - All other characters are copied to + // the output string in the position they appear. + // + // For fixed point formats (formats not containing an 'E+', 'E-', 'e+', or + // 'e-'), the number is rounded to as many decimal places as there are digit + // placeholders to the right of the decimal point. If the format string does + // not contain a decimal point, the number is rounded to the nearest + // integer. If the number has more digits than there are digit placeholders to + // the left of the decimal point, the extra digits are copied to the output + // string immediately before the first digit placeholder. + // + // For scientific formats, the number is rounded to as many significant digits + // as there are digit placeholders in the format string. + // + // To allow for different formatting of positive, negative, and zero values, a + // user-defined format string may contain up to three sections separated by + // semicolons. The results of having one, two, or three sections in the format + // string are described in the table below. + // + // Sections: + // + // One - The format string applies to all values. + // + // Two - The first section applies to positive values + // and zeros, and the second section applies to negative values. If the number + // to be formatted is negative, but becomes zero after rounding according to + // the format in the second section, then the resulting zero is formatted + // according to the first section. + // + // Three - The first section applies to positive + // values, the second section applies to negative values, and the third section + // applies to zeros. The second section may be left empty (by having no + // characters between the semicolons), in which case the first section applies + // to all non-zero values. If the number to be formatted is non-zero, but + // becomes zero after rounding according to the format in the first or second + // section, then the resulting zero is formatted according to the third + // section. + // + // For both standard and user-defined formatting operations on values of type + // float and double, if the value being formatted is a NaN (Not + // a Number) or a positive or negative infinity, then regardless of the format + // string, the resulting string is given by the NaNSymbol, + // PositiveInfinitySymbol, or NegativeInfinitySymbol property of + // the NumberFormatInfo used to format the number. + + internal static partial class Number + { + internal const int DecimalPrecision = 29; // Decimal.DecCalc also uses this value + + // SinglePrecision and DoublePrecision represent the maximum number of digits required + // to guarantee that any given Single or Double can roundtrip. Some numbers may require + // less, but none will require more. + private const int SinglePrecision = 9; + private const int DoublePrecision = 17; + + // SinglePrecisionCustomFormat and DoublePrecisionCustomFormat are used to ensure that + // custom format strings return the same string as in previous releases when the format + // would return x digits or less (where x is the value of the corresponding constant). + // In order to support more digits, we would need to update ParseFormatSpecifier to pre-parse + // the format and determine exactly how many digits are being requested and whether they + // represent "significant digits" or "digits after the decimal point". + private const int SinglePrecisionCustomFormat = 7; + private const int DoublePrecisionCustomFormat = 15; + + private const int DefaultPrecisionExponentialFormat = 6; + + private const int MaxUInt32DecDigits = 10; + private const int CharStackBufferSize = 32; + private const string PosNumberFormat = "#"; + + private static readonly string[] s_singleDigitStringCache = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + + private static readonly string[] s_posCurrencyFormats = + { + "$#", "#$", "$ #", "# $" + }; + + private static readonly string[] s_negCurrencyFormats = + { + "($#)", "-$#", "$-#", "$#-", + "(#$)", "-#$", "#-$", "#$-", + "-# $", "-$ #", "# $-", "$ #-", + "$ -#", "#- $", "($ #)", "(# $)" + }; + + private static readonly string[] s_posPercentFormats = + { + "# %", "#%", "%#", "% #" + }; + + private static readonly string[] s_negPercentFormats = + { + "-# %", "-#%", "-%#", + "%-#", "%#-", + "#-%", "#%-", + "-% #", "# %-", "% #-", + "% -#", "#- %" + }; + + private static readonly string[] s_negNumberFormats = + { + "(#)", "-#", "- #", "#-", "# -", + }; + + public static unsafe string FormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info) + { + char fmt = ParseFormatSpecifier(format, out int digits); + + byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); + + DecimalToNumber(ref value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + + return sb.ToString(); + } + + public static unsafe bool TryFormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) + { + char fmt = ParseFormatSpecifier(format, out int digits); + + byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); + + DecimalToNumber(ref value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + + return sb.TryCopyTo(destination, out charsWritten); + } + + internal static unsafe void DecimalToNumber(ref decimal d, ref NumberBuffer number) + { + byte* buffer = number.GetDigitsPointer(); + number.DigitsCount = DecimalPrecision; + number.IsNegative = d.IsNegative(); + + byte* p = buffer + DecimalPrecision; + while ((d.Mid() | d.High()) != 0) + { + p = UInt32ToDecChars(p, decimal.DecDivMod1E9(ref d), 9); + } + p = UInt32ToDecChars(p, d.Low(), 0); + + int i = (int)((buffer + DecimalPrecision) - p); + + number.DigitsCount = i; + number.Scale = i - d.Scale; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + { + *dst++ = *p++; + } + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + public static string FormatDouble(double value, string format, NumberFormatInfo info) + { + Span stackBuffer = stackalloc char[CharStackBufferSize]; + var sb = new ValueStringBuilder(stackBuffer); + return FormatDouble(ref sb, value, format.AsSpan(), info) ?? sb.ToString(); + } + + public static bool TryFormatDouble(double value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) + { + Span stackBuffer = stackalloc char[CharStackBufferSize]; + var sb = new ValueStringBuilder(stackBuffer); + string s = FormatDouble(ref sb, value, format, info); + return s != null ? + TryCopyTo(s, destination, out charsWritten) : + sb.TryCopyTo(destination, out charsWritten); + } + + private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int precision, NumberFormatInfo info, out bool isSignificantDigits) + { + if (fmt == 0) + { + isSignificantDigits = true; + return precision; + } + + int maxDigits = precision; + + switch (fmt) + { + case 'C': + case 'c': + { + // The currency format uses the precision specifier to indicate the number of + // decimal digits to format. This defaults to NumberFormatInfo.CurrencyDecimalDigits. + + if (precision == -1) + { + precision = info.CurrencyDecimalDigits; + } + isSignificantDigits = false; + + break; + } + + case 'E': + case 'e': + { + // The exponential format uses the precision specifier to indicate the number of + // decimal digits to format. This defaults to 6. However, the exponential format + // also always formats a single integral digit, so we need to increase the precision + // specifier and treat it as the number of significant digits to account for this. + + if (precision == -1) + { + precision = DefaultPrecisionExponentialFormat; + } + + precision++; + isSignificantDigits = true; + + break; + } + + case 'F': + case 'f': + case 'N': + case 'n': + { + // The fixed-point and number formats use the precision specifier to indicate the number + // of decimal digits to format. This defaults to NumberFormatInfo.NumberDecimalDigits. + + if (precision == -1) + { + precision = info.NumberDecimalDigits; + } + isSignificantDigits = false; + + break; + } + + case 'G': + case 'g': + { + // The general format uses the precision specifier to indicate the number of significant + // digits to format. This defaults to the shortest roundtrippable string. Additionally, + // given that we can't return zero significant digits, we treat 0 as returning the shortest + // roundtrippable string as well. + + if (precision == 0) + { + precision = -1; + } + isSignificantDigits = true; + + break; + } + + case 'P': + case 'p': + { + // The percent format uses the precision specifier to indicate the number of + // decimal digits to format. This defaults to NumberFormatInfo.PercentDecimalDigits. + // However, the percent format also always multiplies the number by 100, so we need + // to increase the precision specifier to ensure we get the appropriate number of digits. + + if (precision == -1) + { + precision = info.PercentDecimalDigits; + } + + precision += 2; + isSignificantDigits = false; + + break; + } + + case 'R': + case 'r': + { + // The roundtrip format ignores the precision specifier and always returns the shortest + // roundtrippable string. + + precision = -1; + isSignificantDigits = true; + + break; + } + + default: + { + throw new FormatException(SR.Argument_BadFormatSpecifier); + } + } + + return maxDigits; + } + + /// Formats the specified value according to the specified format and info. + /// + /// Non-null if an existing string can be returned, in which case the builder will be unmodified. + /// Null if no existing string was returned, in which case the formatted output is in the builder. + /// + private static unsafe string FormatDouble(ref ValueStringBuilder sb, double value, ReadOnlySpan format, NumberFormatInfo info) + { + if (!double.IsFinite(value)) + { + if (double.IsNaN(value)) + { + return info.NaNSymbol; + } + + return double.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; + } + + char fmt = ParseFormatSpecifier(format, out int precision); + byte* pDigits = stackalloc byte[DoubleNumberBufferLength]; + + if (fmt == '\0') + { + // For back-compat we currently specially treat the precision for custom + // format specifiers. The constant has more details as to why. + precision = DoublePrecisionCustomFormat; + } + + NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, DoubleNumberBufferLength); + number.IsNegative = double.IsNegative(value); + + // We need to track the original precision requested since some formats + // accept values like 0 and others may require additional fixups. + int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(fmt, ref precision, info, out bool isSignificantDigits); + + if ((value != 0.0) && (!isSignificantDigits || !Grisu3.TryRunDouble(value, precision, ref number))) + { + Dragon4Double(value, precision, isSignificantDigits, ref number); + } + + number.CheckConsistency(); + + // When the number is known to be roundtrippable (either because we requested it be, or + // because we know we have enough digits to satisfy roundtrippability), we should validate + // that the number actually roundtrips back to the original result. + + Debug.Assert(((precision != -1) && (precision < DoublePrecision)) || (BitConverter.DoubleToInt64Bits(value) == BitConverter.DoubleToInt64Bits(NumberToDouble(ref number)))); + + if (fmt != 0) + { + if (precision == -1) + { + Debug.Assert((fmt == 'G') || (fmt == 'g') || (fmt == 'R') || (fmt == 'r')); + + // For the roundtrip and general format specifiers, when returning the shortest roundtrippable + // string, we need to update the maximum number of digits to be the greater of number.DigitsCount + // or DoublePrecision. This ensures that we continue returning "pretty" strings for values with + // less digits. One example this fixes is "-60", which would otherwise be formatted as "-6E+01" + // since DigitsCount would be 1 and the formatter would almost immediately switch to scientific notation. + + nMaxDigits = Math.Max(number.DigitsCount, DoublePrecision); + } + NumberToString(ref sb, ref number, fmt, nMaxDigits, info); + } + else + { + Debug.Assert(precision == DoublePrecisionCustomFormat); + NumberToStringFormat(ref sb, ref number, format, info); + } + return null; + } + + public static string FormatSingle(float value, string format, NumberFormatInfo info) + { + Span stackBuffer = stackalloc char[CharStackBufferSize]; + var sb = new ValueStringBuilder(stackBuffer); + return FormatSingle(ref sb, value, format.AsSpan(), info) ?? sb.ToString(); + } + + public static bool TryFormatSingle(float value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) + { + Span stackBuffer = stackalloc char[CharStackBufferSize]; + var sb = new ValueStringBuilder(stackBuffer); + string s = FormatSingle(ref sb, value, format, info); + return s != null ? + TryCopyTo(s, destination, out charsWritten) : + sb.TryCopyTo(destination, out charsWritten); + } + + /// Formats the specified value according to the specified format and info. + /// + /// Non-null if an existing string can be returned, in which case the builder will be unmodified. + /// Null if no existing string was returned, in which case the formatted output is in the builder. + /// + private static unsafe string FormatSingle(ref ValueStringBuilder sb, float value, ReadOnlySpan format, NumberFormatInfo info) + { + if (!float.IsFinite(value)) + { + if (float.IsNaN(value)) + { + return info.NaNSymbol; + } + + return float.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; + } + + char fmt = ParseFormatSpecifier(format, out int precision); + byte* pDigits = stackalloc byte[SingleNumberBufferLength]; + + if (fmt == '\0') + { + // For back-compat we currently specially treat the precision for custom + // format specifiers. The constant has more details as to why. + precision = SinglePrecisionCustomFormat; + } + + NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, SingleNumberBufferLength); + number.IsNegative = float.IsNegative(value); + + // We need to track the original precision requested since some formats + // accept values like 0 and others may require additional fixups. + int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(fmt, ref precision, info, out bool isSignificantDigits); + + if ((value != 0.0f) && (!isSignificantDigits || !Grisu3.TryRunSingle(value, precision, ref number))) + { + Dragon4Single(value, precision, isSignificantDigits, ref number); + } + + number.CheckConsistency(); + + // When the number is known to be roundtrippable (either because we requested it be, or + // because we know we have enough digits to satisfy roundtrippability), we should validate + // that the number actually roundtrips back to the original result. + + Debug.Assert(((precision != -1) && (precision < SinglePrecision)) || (BitConverter.SingleToInt32Bits(value) == BitConverter.SingleToInt32Bits(NumberToSingle(ref number)))); + + if (fmt != 0) + { + if (precision == -1) + { + Debug.Assert((fmt == 'G') || (fmt == 'g') || (fmt == 'R') || (fmt == 'r')); + + // For the roundtrip and general format specifiers, when returning the shortest roundtrippable + // string, we need to update the maximum number of digits to be the greater of number.DigitsCount + // or SinglePrecision. This ensures that we continue returning "pretty" strings for values with + // less digits. One example this fixes is "-60", which would otherwise be formatted as "-6E+01" + // since DigitsCount would be 1 and the formatter would almost immediately switch to scientific notation. + + nMaxDigits = Math.Max(number.DigitsCount, SinglePrecision); + } + NumberToString(ref sb, ref number, fmt, nMaxDigits, info); + } + else + { + Debug.Assert(precision == SinglePrecisionCustomFormat); + NumberToStringFormat(ref sb, ref number, format, info); + } + return null; + } + + private static bool TryCopyTo(string source, Span destination, out int charsWritten) + { + Debug.Assert(source != null); + + if (source.AsSpan().TryCopyTo(destination)) + { + charsWritten = source.Length; + return true; + } + + charsWritten = 0; + return false; + } + + public static unsafe string FormatInt32(int value, ReadOnlySpan format, IFormatProvider provider) + { + // Fast path for default format with a non-negative value + if (value >= 0 && format.Length == 0) + { + return UInt32ToDecStr((uint)value, digits: -1); + } + + char fmt = ParseFormatSpecifier(format, out int 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 ? + UInt32ToDecStr((uint)value, digits) : + NegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign); + } + 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 Int32ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Int32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); + + Int32ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.ToString(); + } + } + + public static unsafe bool TryFormatInt32(int value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) + { + // Fast path for default format with a non-negative value + if (value >= 0 && format.Length == 0) + { + return TryUInt32ToDecStr((uint)value, digits: -1, destination, out charsWritten); + } + + char fmt = ParseFormatSpecifier(format, out int 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, NumberFormatInfo.GetInstance(provider).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 + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Int32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); + + Int32ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.TryCopyTo(destination, out charsWritten); + } + } + + public static unsafe string FormatUInt32(uint value, ReadOnlySpan format, IFormatProvider provider) + { + // Fast path for default format + if (format.Length == 0) + { + return UInt32ToDecStr(value, digits: -1); + } + + char fmt = ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') + { + return UInt32ToDecStr(value, digits); + } + 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 Int32ToHexStr((int)value, (char)(fmt - ('X' - 'A' + 10)), digits); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); + + UInt32ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.ToString(); + } + } + + public static unsafe bool TryFormatUInt32(uint value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) + { + // Fast path for default format + if (format.Length == 0) + { + return TryUInt32ToDecStr(value, digits: -1, destination, out charsWritten); + } + + char fmt = ParseFormatSpecifier(format, out int 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 + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); + + UInt32ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.TryCopyTo(destination, out charsWritten); + } + } + + public static unsafe string FormatInt64(long value, ReadOnlySpan format, IFormatProvider provider) + { + // Fast path for default format with a non-negative value + if (value >= 0 && format.Length == 0) + { + return UInt64ToDecStr((ulong)value, digits: -1); + } + + char fmt = ParseFormatSpecifier(format, out int 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 ? + UInt64ToDecStr((ulong)value, digits) : + NegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign); + } + 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 Int64ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Int64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); + + Int64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.ToString(); + } + } + + public static unsafe bool TryFormatInt64(long value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) + { + // Fast path for default format with a non-negative value + if (value >= 0 && format.Length == 0) + { + return TryUInt64ToDecStr((ulong)value, digits: -1, destination, out charsWritten); + } + + char fmt = ParseFormatSpecifier(format, out int 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, NumberFormatInfo.GetInstance(provider).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 + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Int64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); + + Int64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.TryCopyTo(destination, out charsWritten); + } + } + + public static unsafe string FormatUInt64(ulong value, ReadOnlySpan format, IFormatProvider provider) + { + // Fast path for default format + if (format.Length == 0) + { + return UInt64ToDecStr(value, digits: -1); + } + + char fmt = ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') + { + return UInt64ToDecStr(value, digits); + } + 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 Int64ToHexStr((long)value, (char)(fmt - ('X' - 'A' + 10)), digits); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); + + UInt64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.ToString(); + } + } + + public static unsafe bool TryFormatUInt64(ulong value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) + { + // Fast path for default format + if (format.Length == 0) + { + return TryUInt64ToDecStr(value, digits: -1, destination, out charsWritten); + } + + char fmt = ParseFormatSpecifier(format, out int 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 + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); + + UInt64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.TryCopyTo(destination, out charsWritten); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // called from only one location + private static unsafe void Int32ToNumber(int value, ref NumberBuffer number) + { + number.DigitsCount = Int32Precision; + + if (value >= 0) + { + number.IsNegative = false; + } + else + { + number.IsNegative = true; + value = -value; + } + + byte* buffer = number.GetDigitsPointer(); + byte* p = UInt32ToDecChars(buffer + Int32Precision, (uint)value, 0); + + int i = (int)(buffer + Int32Precision - p); + + number.DigitsCount = i; + number.Scale = i; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + *dst++ = *p++; + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + private static unsafe string NegativeInt32ToDecStr(int value, int digits, string sNegative) + { + Debug.Assert(value < 0); + + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; + string result = string.FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, string sNegative, Span destination, out int charsWritten) + { + Debug.Assert(value < 0); + + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe string Int32ToHexStr(int value, char hexBase, int digits) + { + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); + string result = string.FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span destination, out int charsWritten) + { + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe char* Int32ToHexChars(char* buffer, uint value, int hexBase, int digits) + { + while (--digits >= 0 || value != 0) + { + byte digit = (byte)(value & 0xF); + *(--buffer) = (char)(digit + (digit < 10 ? (byte)'0' : hexBase)); + value >>= 4; + } + return buffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // called from only one location + private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) + { + number.DigitsCount = UInt32Precision; + number.IsNegative = false; + + byte* buffer = number.GetDigitsPointer(); + byte* p = UInt32ToDecChars(buffer + UInt32Precision, value, 0); + + int i = (int)(buffer + UInt32Precision - p); + + number.DigitsCount = i; + number.Scale = i; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + *dst++ = *p++; + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + internal static unsafe byte* UInt32ToDecChars(byte* bufferEnd, uint value, int digits) + { + while (--digits >= 0 || value != 0) + { + value = Math.DivRem(value, 10, out uint remainder); + *(--bufferEnd) = (byte)(remainder + '0'); + } + return bufferEnd; + } + + internal static unsafe char* UInt32ToDecChars(char* bufferEnd, uint value, int digits) + { + while (--digits >= 0 || value != 0) + { + value = Math.DivRem(value, 10, out uint remainder); + *(--bufferEnd) = (char)(remainder + '0'); + } + return bufferEnd; + } + + internal static unsafe string UInt32ToDecStr(uint value, int digits) + { + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); + + // For single-digit values that are very common, especially 0 and 1, just return cached strings. + if (bufferLength == 1) + { + return s_singleDigitStringCache[value]; + } + + string result = string.FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = buffer + bufferLength; + if (digits <= 1) + { + do + { + value = Math.DivRem(value, 10, out uint remainder); + *(--p) = (char)(remainder + '0'); + } + while (value != 0); + } + else + { + p = UInt32ToDecChars(p, value, digits); + } + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span destination, out int charsWritten) + { + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = buffer + bufferLength; + if (digits <= 1) + { + do + { + value = Math.DivRem(value, 10, out uint remainder); + *(--p) = (char)(remainder + '0'); + } + while (value != 0); + } + else + { + p = UInt32ToDecChars(p, value, digits); + } + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe void Int64ToNumber(long input, ref NumberBuffer number) + { + ulong value = (ulong)input; + number.IsNegative = input < 0; + number.DigitsCount = Int64Precision; + if (number.IsNegative) + { + value = (ulong)(-input); + } + + byte* buffer = number.GetDigitsPointer(); + byte* p = buffer + Int64Precision; + while (High32(value) != 0) + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + p = UInt32ToDecChars(p, Low32(value), 0); + + int i = (int)(buffer + Int64Precision - p); + + number.DigitsCount = i; + number.Scale = i; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + *dst++ = *p++; + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + private static unsafe string NegativeInt64ToDecStr(long input, int digits, string sNegative) + { + Debug.Assert(input < 0); + + if (digits < 1) + { + digits = 1; + } + + ulong value = (ulong)(-input); + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)) + sNegative.Length; + string result = string.FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = buffer + bufferLength; + while (High32(value) != 0) + { + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + digits -= 9; + } + p = UInt32ToDecChars(p, Low32(value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryNegativeInt64ToDecStr(long input, int digits, string sNegative, Span destination, out int charsWritten) + { + Debug.Assert(input < 0); + + if (digits < 1) + { + digits = 1; + } + + ulong value = (ulong)(-input); + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((ulong)(-input))) + sNegative.Length; + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = buffer + bufferLength; + while (High32(value) != 0) + { + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + digits -= 9; + } + p = UInt32ToDecChars(p, Low32(value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe string Int64ToHexStr(long value, char hexBase, int digits) + { + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); + string result = string.FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = buffer + bufferLength; + if (High32((ulong)value) != 0) + { + p = Int32ToHexChars(p, Low32((ulong)value), hexBase, 8); + p = Int32ToHexChars(p, High32((ulong)value), hexBase, digits - 8); + } + else + { + p = Int32ToHexChars(p, Low32((ulong)value), hexBase, Math.Max(digits, 1)); + } + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span destination, out int charsWritten) + { + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = buffer + bufferLength; + if (High32((ulong)value) != 0) + { + p = Int32ToHexChars(p, Low32((ulong)value), hexBase, 8); + p = Int32ToHexChars(p, High32((ulong)value), hexBase, digits - 8); + } + else + { + p = Int32ToHexChars(p, Low32((ulong)value), hexBase, Math.Max(digits, 1)); + } + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number) + { + number.DigitsCount = UInt64Precision; + number.IsNegative = false; + + byte* buffer = number.GetDigitsPointer(); + byte* p = buffer + UInt64Precision; + + while (High32(value) != 0) + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + p = UInt32ToDecChars(p, Low32(value), 0); + + int i = (int)(buffer + UInt64Precision - p); + + number.DigitsCount = i; + number.Scale = i; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + *dst++ = *p++; + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + internal static unsafe string UInt64ToDecStr(ulong value, int digits) + { + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); + + // For single-digit values that are very common, especially 0 and 1, just return cached strings. + if (bufferLength == 1) + { + return s_singleDigitStringCache[value]; + } + + string result = string.FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = buffer + bufferLength; + while (High32(value) != 0) + { + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + digits -= 9; + } + p = UInt32ToDecChars(p, Low32(value), digits); + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span destination, out int charsWritten) + { + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = buffer + bufferLength; + while (High32(value) != 0) + { + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + digits -= 9; + } + p = UInt32ToDecChars(p, Low32(value), digits); + Debug.Assert(p == buffer); + } + return true; + } + + internal static unsafe char ParseFormatSpecifier(ReadOnlySpan format, out int digits) + { + char c = default; + if (format.Length > 0) + { + // If the format begins with a symbol, see if it's a standard format + // with or without a specified number of digits. + c = format[0]; + if ((uint)(c - 'A') <= 'Z' - 'A' || + (uint)(c - 'a') <= 'z' - 'a') + { + // Fast path for sole symbol, e.g. "D" + if (format.Length == 1) + { + digits = -1; + return c; + } + + if (format.Length == 2) + { + // Fast path for symbol and single digit, e.g. "X4" + int d = format[1] - '0'; + if ((uint)d < 10) + { + digits = d; + return c; + } + } + else if (format.Length == 3) + { + // Fast path for symbol and double digit, e.g. "F12" + int d1 = format[1] - '0', d2 = format[2] - '0'; + if ((uint)d1 < 10 && (uint)d2 < 10) + { + digits = d1 * 10 + d2; + return c; + } + } + + // Fallback for symbol and any length digits. The digits value must be >= 0 && <= 99, + // but it can begin with any number of 0s, and thus we may need to check more than two + // digits. Further, for compat, we need to stop when we hit a null char. + int n = 0; + int i = 1; + while (i < format.Length && (((uint)format[i] - '0') < 10) && n < 10) + { + n = (n * 10) + format[i++] - '0'; + } + + // If we're at the end of the digits rather than having stopped because we hit something + // other than a digit or overflowed, return the standard format info. + if (i == format.Length || format[i] == '\0') + { + digits = n; + return c; + } + } + } + + // Default empty format to be "G"; custom format is signified with '\0'. + digits = -1; + return format.Length == 0 || c == '\0' ? // For compat, treat '\0' as the end of the specifier, even if the specifier extends beyond it. + 'G' : + '\0'; + } + + internal static unsafe void NumberToString(ref ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info) + { + number.CheckConsistency(); + bool isCorrectlyRounded = (number.Kind == NumberBufferKind.FloatingPoint); + + switch (format) + { + case 'C': + case 'c': + { + if (nMaxDigits < 0) + nMaxDigits = info.CurrencyDecimalDigits; + + RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); // Don't change this line to use digPos since digCount could have its sign changed. + + FormatCurrency(ref sb, ref number, nMaxDigits, info); + + break; + } + + case 'F': + case 'f': + { + if (nMaxDigits < 0) + nMaxDigits = info.NumberDecimalDigits; + + RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); + + if (number.IsNegative) + sb.Append(info.NegativeSign); + + FormatFixed(ref sb, ref number, nMaxDigits, null, info.NumberDecimalSeparator, null); + + break; + } + + case 'N': + case 'n': + { + if (nMaxDigits < 0) + nMaxDigits = info.NumberDecimalDigits; // Since we are using digits in our calculation + + RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); + + FormatNumber(ref sb, ref number, nMaxDigits, info); + + break; + } + + case 'E': + case 'e': + { + if (nMaxDigits < 0) + nMaxDigits = DefaultPrecisionExponentialFormat; + nMaxDigits++; + + RoundNumber(ref number, nMaxDigits, isCorrectlyRounded); + + if (number.IsNegative) + sb.Append(info.NegativeSign); + + FormatScientific(ref sb, ref number, nMaxDigits, info, format); + + break; + } + + case 'G': + case 'g': + { + bool noRounding = false; + if (nMaxDigits < 1) + { + if ((number.Kind == NumberBufferKind.Decimal) && (nMaxDigits == -1)) + { + noRounding = true; // Turn off rounding for ECMA compliance to output trailing 0's after decimal as significant + + if (number.Digits[0] == 0) + { + // -0 should be formatted as 0 for decimal. This is normally handled by RoundNumber (which we are skipping) + goto SkipSign; + } + + goto SkipRounding; + } + else + { + // This ensures that the PAL code pads out to the correct place even when we use the default precision + nMaxDigits = number.DigitsCount; + } + } + + RoundNumber(ref number, nMaxDigits, isCorrectlyRounded); + + SkipRounding: + if (number.IsNegative) + sb.Append(info.NegativeSign); + + SkipSign: + FormatGeneral(ref sb, ref number, nMaxDigits, info, (char)(format - ('G' - 'E')), noRounding); + + break; + } + + case 'P': + case 'p': + { + if (nMaxDigits < 0) + nMaxDigits = info.PercentDecimalDigits; + number.Scale += 2; + + RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); + + FormatPercent(ref sb, ref number, nMaxDigits, info); + + break; + } + + case 'R': + case 'r': + { + if (number.Kind != NumberBufferKind.FloatingPoint) + { + goto default; + } + + format = (char)(format - ('R' - 'G')); + Debug.Assert((format == 'G') || (format == 'g')); + goto case 'G'; + } + + default: + throw new FormatException(SR.Argument_BadFormatSpecifier); + } + } + + internal static unsafe void NumberToStringFormat(ref ValueStringBuilder sb, ref NumberBuffer number, ReadOnlySpan format, NumberFormatInfo info) + { + number.CheckConsistency(); + + int digitCount; + int decimalPos; + int firstDigit; + int lastDigit; + int digPos; + bool scientific; + int thousandPos; + int thousandCount = 0; + bool thousandSeps; + int scaleAdjust; + int adjust; + + int section; + int src; + byte* dig = number.GetDigitsPointer(); + char ch; + + section = FindSection(format, dig[0] == 0 ? 2 : number.IsNegative ? 1 : 0); + + while (true) + { + digitCount = 0; + decimalPos = -1; + firstDigit = 0x7FFFFFFF; + lastDigit = 0; + scientific = false; + thousandPos = -1; + thousandSeps = false; + scaleAdjust = 0; + src = section; + + fixed (char* pFormat = &MemoryMarshal.GetReference(format)) + { + while (src < format.Length && (ch = pFormat[src++]) != 0 && ch != ';') + { + switch (ch) + { + case '#': + digitCount++; + break; + case '0': + if (firstDigit == 0x7FFFFFFF) + firstDigit = digitCount; + digitCount++; + lastDigit = digitCount; + break; + case '.': + if (decimalPos < 0) + decimalPos = digitCount; + break; + case ',': + if (digitCount > 0 && decimalPos < 0) + { + if (thousandPos >= 0) + { + if (thousandPos == digitCount) + { + thousandCount++; + break; + } + thousandSeps = true; + } + thousandPos = digitCount; + thousandCount = 1; + } + break; + case '%': + scaleAdjust += 2; + break; + case '\x2030': + scaleAdjust += 3; + break; + case '\'': + case '"': + while (src < format.Length && pFormat[src] != 0 && pFormat[src++] != ch) + ; + break; + case '\\': + if (src < format.Length && pFormat[src] != 0) + src++; + break; + case 'E': + case 'e': + if ((src < format.Length && pFormat[src] == '0') || + (src + 1 < format.Length && (pFormat[src] == '+' || pFormat[src] == '-') && pFormat[src + 1] == '0')) + { + while (++src < format.Length && pFormat[src] == '0') + ; + scientific = true; + } + break; + } + } + } + + if (decimalPos < 0) + decimalPos = digitCount; + + if (thousandPos >= 0) + { + if (thousandPos == decimalPos) + scaleAdjust -= thousandCount * 3; + else + thousandSeps = true; + } + + if (dig[0] != 0) + { + number.Scale += scaleAdjust; + int pos = scientific ? digitCount : number.Scale + digitCount - decimalPos; + RoundNumber(ref number, pos, isCorrectlyRounded: false); + if (dig[0] == 0) + { + src = FindSection(format, 2); + if (src != section) + { + section = src; + continue; + } + } + } + else + { + if (number.Kind != NumberBufferKind.FloatingPoint) + { + // The integer types don't have a concept of -0 and decimal always format -0 as 0 + number.IsNegative = false; + } + number.Scale = 0; // Decimals with scale ('0.00') should be rounded. + } + + break; + } + + firstDigit = firstDigit < decimalPos ? decimalPos - firstDigit : 0; + lastDigit = lastDigit > decimalPos ? decimalPos - lastDigit : 0; + if (scientific) + { + digPos = decimalPos; + adjust = 0; + } + else + { + digPos = number.Scale > decimalPos ? number.Scale : decimalPos; + adjust = number.Scale - decimalPos; + } + src = section; + + // Adjust can be negative, so we make this an int instead of an unsigned int. + // Adjust represents the number of characters over the formatting e.g. format string is "0000" and you are trying to + // format 100000 (6 digits). Means adjust will be 2. On the other hand if you are trying to format 10 adjust will be + // -2 and we'll need to fixup these digits with 0 padding if we have 0 formatting as in this example. + Span thousandsSepPos = stackalloc int[4]; + int thousandsSepCtr = -1; + + if (thousandSeps) + { + // We need to precompute this outside the number formatting loop + if (info.NumberGroupSeparator.Length > 0) + { + // We need this array to figure out where to insert the thousands separator. We would have to traverse the string + // backwards. PIC formatting always traverses forwards. These indices are precomputed to tell us where to insert + // the thousands separator so we can get away with traversing forwards. Note we only have to compute up to digPos. + // The max is not bound since you can have formatting strings of the form "000,000..", and this + // should handle that case too. + + int[] groupDigits = info._numberGroupSizes; + + int groupSizeIndex = 0; // Index into the groupDigits array. + int groupTotalSizeCount = 0; + int groupSizeLen = groupDigits.Length; // The length of groupDigits array. + if (groupSizeLen != 0) + groupTotalSizeCount = groupDigits[groupSizeIndex]; // The current running total of group size. + int groupSize = groupTotalSizeCount; + + int totalDigits = digPos + ((adjust < 0) ? adjust : 0); // Actual number of digits in o/p + int numDigits = (firstDigit > totalDigits) ? firstDigit : totalDigits; + while (numDigits > groupTotalSizeCount) + { + if (groupSize == 0) + break; + ++thousandsSepCtr; + if (thousandsSepCtr >= thousandsSepPos.Length) + { + var newThousandsSepPos = new int[thousandsSepPos.Length * 2]; + thousandsSepPos.CopyTo(newThousandsSepPos); + thousandsSepPos = newThousandsSepPos; + } + + thousandsSepPos[thousandsSepCtr] = groupTotalSizeCount; + if (groupSizeIndex < groupSizeLen - 1) + { + groupSizeIndex++; + groupSize = groupDigits[groupSizeIndex]; + } + groupTotalSizeCount += groupSize; + } + } + } + + if (number.IsNegative && (section == 0) && (number.Scale != 0)) + sb.Append(info.NegativeSign); + + bool decimalWritten = false; + + fixed (char* pFormat = &MemoryMarshal.GetReference(format)) + { + byte* cur = dig; + + while (src < format.Length && (ch = pFormat[src++]) != 0 && ch != ';') + { + if (adjust > 0) + { + switch (ch) + { + case '#': + case '0': + case '.': + while (adjust > 0) + { + // digPos will be one greater than thousandsSepPos[thousandsSepCtr] since we are at + // the character after which the groupSeparator needs to be appended. + sb.Append(*cur != 0 ? (char)(*cur++) : '0'); + if (thousandSeps && digPos > 1 && thousandsSepCtr >= 0) + { + if (digPos == thousandsSepPos[thousandsSepCtr] + 1) + { + sb.Append(info.NumberGroupSeparator); + thousandsSepCtr--; + } + } + digPos--; + adjust--; + } + break; + } + } + + switch (ch) + { + case '#': + case '0': + { + if (adjust < 0) + { + adjust++; + ch = digPos <= firstDigit ? '0' : '\0'; + } + else + { + ch = *cur != 0 ? (char)(*cur++) : digPos > lastDigit ? '0' : '\0'; + } + if (ch != 0) + { + sb.Append(ch); + if (thousandSeps && digPos > 1 && thousandsSepCtr >= 0) + { + if (digPos == thousandsSepPos[thousandsSepCtr] + 1) + { + sb.Append(info.NumberGroupSeparator); + thousandsSepCtr--; + } + } + } + + digPos--; + break; + } + case '.': + { + if (digPos != 0 || decimalWritten) + { + // For compatibility, don't echo repeated decimals + break; + } + // If the format has trailing zeros or the format has a decimal and digits remain + if (lastDigit < 0 || (decimalPos < digitCount && *cur != 0)) + { + sb.Append(info.NumberDecimalSeparator); + decimalWritten = true; + } + break; + } + case '\x2030': + sb.Append(info.PerMilleSymbol); + break; + case '%': + sb.Append(info.PercentSymbol); + break; + case ',': + break; + case '\'': + case '"': + while (src < format.Length && pFormat[src] != 0 && pFormat[src] != ch) + sb.Append(pFormat[src++]); + if (src < format.Length && pFormat[src] != 0) + src++; + break; + case '\\': + if (src < format.Length && pFormat[src] != 0) + sb.Append(pFormat[src++]); + break; + case 'E': + case 'e': + { + bool positiveSign = false; + int i = 0; + if (scientific) + { + if (src < format.Length && pFormat[src] == '0') + { + // Handles E0, which should format the same as E-0 + i++; + } + else if (src + 1 < format.Length && pFormat[src] == '+' && pFormat[src + 1] == '0') + { + // Handles E+0 + positiveSign = true; + } + else if (src + 1 < format.Length && pFormat[src] == '-' && pFormat[src + 1] == '0') + { + // Handles E-0 + // Do nothing, this is just a place holder s.t. we don't break out of the loop. + } + else + { + sb.Append(ch); + break; + } + + while (++src < format.Length && pFormat[src] == '0') + i++; + if (i > 10) + i = 10; + + int exp = dig[0] == 0 ? 0 : number.Scale - decimalPos; + FormatExponent(ref sb, info, exp, ch, i, positiveSign); + scientific = false; + } + else + { + sb.Append(ch); // Copy E or e to output + if (src < format.Length) + { + if (pFormat[src] == '+' || pFormat[src] == '-') + sb.Append(pFormat[src++]); + while (src < format.Length && pFormat[src] == '0') + sb.Append(pFormat[src++]); + } + } + break; + } + default: + sb.Append(ch); + break; + } + } + } + + if (number.IsNegative && (section == 0) && (number.Scale == 0) && (sb.Length > 0)) + sb.Insert(0, info.NegativeSign); + } + + private static void FormatCurrency(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) + { + string fmt = number.IsNegative ? + s_negCurrencyFormats[info.CurrencyNegativePattern] : + s_posCurrencyFormats[info.CurrencyPositivePattern]; + + foreach (char ch in fmt) + { + switch (ch) + { + case '#': + FormatFixed(ref sb, ref number, nMaxDigits, info._currencyGroupSizes, info.CurrencyDecimalSeparator, info.CurrencyGroupSeparator); + break; + case '-': + sb.Append(info.NegativeSign); + break; + case '$': + sb.Append(info.CurrencySymbol); + break; + default: + sb.Append(ch); + break; + } + } + } + + private static unsafe void FormatFixed(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, int[] groupDigits, string sDecimal, string sGroup) + { + int digPos = number.Scale; + byte* dig = number.GetDigitsPointer(); + + if (digPos > 0) + { + if (groupDigits != null) + { + Debug.Assert(sGroup != null, "Must be nulll when groupDigits != null"); + int groupSizeIndex = 0; // Index into the groupDigits array. + int bufferSize = digPos; // The length of the result buffer string. + int groupSize = 0; // The current group size. + + // Find out the size of the string buffer for the result. + if (groupDigits.Length != 0) // You can pass in 0 length arrays + { + int groupSizeCount = groupDigits[groupSizeIndex]; // The current total of group size. + + while (digPos > groupSizeCount) + { + groupSize = groupDigits[groupSizeIndex]; + if (groupSize == 0) + break; + + bufferSize += sGroup.Length; + if (groupSizeIndex < groupDigits.Length - 1) + groupSizeIndex++; + + groupSizeCount += groupDigits[groupSizeIndex]; + if (groupSizeCount < 0 || bufferSize < 0) + throw new ArgumentOutOfRangeException(); // If we overflow + } + + groupSize = groupSizeCount == 0 ? 0 : groupDigits[0]; // If you passed in an array with one entry as 0, groupSizeCount == 0 + } + + groupSizeIndex = 0; + int digitCount = 0; + int digLength = number.DigitsCount; + int digStart = (digPos < digLength) ? digPos : digLength; + fixed (char* spanPtr = &MemoryMarshal.GetReference(sb.AppendSpan(bufferSize))) + { + char* p = spanPtr + bufferSize - 1; + for (int i = digPos - 1; i >= 0; i--) + { + *(p--) = (i < digStart) ? (char)(dig[i]) : '0'; + + if (groupSize > 0) + { + digitCount++; + if ((digitCount == groupSize) && (i != 0)) + { + for (int j = sGroup.Length - 1; j >= 0; j--) + *(p--) = sGroup[j]; + + if (groupSizeIndex < groupDigits.Length - 1) + { + groupSizeIndex++; + groupSize = groupDigits[groupSizeIndex]; + } + digitCount = 0; + } + } + } + + Debug.Assert(p >= spanPtr - 1, "Underflow"); + dig += digStart; + } + } + else + { + do + { + sb.Append(*dig != 0 ? (char)(*dig++) : '0'); + } + while (--digPos > 0); + } + } + else + { + sb.Append('0'); + } + + if (nMaxDigits > 0) + { + Debug.Assert(sDecimal != null); + sb.Append(sDecimal); + if ((digPos < 0) && (nMaxDigits > 0)) + { + int zeroes = Math.Min(-digPos, nMaxDigits); + sb.Append('0', zeroes); + digPos += zeroes; + nMaxDigits -= zeroes; + } + + while (nMaxDigits > 0) + { + sb.Append((*dig != 0) ? (char)(*dig++) : '0'); + nMaxDigits--; + } + } + } + + private static void FormatNumber(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) + { + string fmt = number.IsNegative ? + s_negNumberFormats[info.NumberNegativePattern] : + PosNumberFormat; + + foreach (char ch in fmt) + { + switch (ch) + { + case '#': + FormatFixed(ref sb, ref number, nMaxDigits, info._numberGroupSizes, info.NumberDecimalSeparator, info.NumberGroupSeparator); + break; + case '-': + sb.Append(info.NegativeSign); + break; + default: + sb.Append(ch); + break; + } + } + } + + private static unsafe void FormatScientific(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar) + { + byte* dig = number.GetDigitsPointer(); + + sb.Append((*dig != 0) ? (char)(*dig++) : '0'); + + if (nMaxDigits != 1) // For E0 we would like to suppress the decimal point + sb.Append(info.NumberDecimalSeparator); + + while (--nMaxDigits > 0) + sb.Append((*dig != 0) ? (char)(*dig++) : '0'); + + int e = number.Digits[0] == 0 ? 0 : number.Scale - 1; + FormatExponent(ref sb, info, e, expChar, 3, true); + } + + private static unsafe void FormatExponent(ref ValueStringBuilder sb, NumberFormatInfo info, int value, char expChar, int minDigits, bool positiveSign) + { + sb.Append(expChar); + + if (value < 0) + { + sb.Append(info.NegativeSign); + value = -value; + } + else + { + if (positiveSign) + sb.Append(info.PositiveSign); + } + + char* digits = stackalloc char[MaxUInt32DecDigits]; + char* p = UInt32ToDecChars(digits + MaxUInt32DecDigits, (uint)value, minDigits); + sb.Append(p, (int)(digits + MaxUInt32DecDigits - p)); + } + + private static unsafe void FormatGeneral(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar, bool bSuppressScientific) + { + int digPos = number.Scale; + bool scientific = false; + + if (!bSuppressScientific) + { + // Don't switch to scientific notation + if (digPos > nMaxDigits || digPos < -3) + { + digPos = 1; + scientific = true; + } + } + + byte* dig = number.GetDigitsPointer(); + + if (digPos > 0) + { + do + { + sb.Append((*dig != 0) ? (char)(*dig++) : '0'); + } while (--digPos > 0); + } + else + { + sb.Append('0'); + } + + if (*dig != 0 || digPos < 0) + { + sb.Append(info.NumberDecimalSeparator); + + while (digPos < 0) + { + sb.Append('0'); + digPos++; + } + + while (*dig != 0) + sb.Append((char)(*dig++)); + } + + if (scientific) + FormatExponent(ref sb, info, number.Scale - 1, expChar, 2, true); + } + + private static void FormatPercent(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) + { + string fmt = number.IsNegative ? + s_negPercentFormats[info.PercentNegativePattern] : + s_posPercentFormats[info.PercentPositivePattern]; + + foreach (char ch in fmt) + { + switch (ch) + { + case '#': + FormatFixed(ref sb, ref number, nMaxDigits, info._percentGroupSizes, info.PercentDecimalSeparator, info.PercentGroupSeparator); + break; + case '-': + sb.Append(info.NegativeSign); + break; + case '%': + sb.Append(info.PercentSymbol); + break; + default: + sb.Append(ch); + break; + } + } + } + + internal static unsafe void RoundNumber(ref NumberBuffer number, int pos, bool isCorrectlyRounded) + { + byte* dig = number.GetDigitsPointer(); + + int i = 0; + while (i < pos && dig[i] != '\0') + i++; + + if ((i == pos) && ShouldRoundUp(dig, i, number.Kind, isCorrectlyRounded)) + { + while (i > 0 && dig[i - 1] == '9') + i--; + + if (i > 0) + { + dig[i - 1]++; + } + else + { + number.Scale++; + dig[0] = (byte)('1'); + i = 1; + } + } + else + { + while (i > 0 && dig[i - 1] == '0') + i--; + } + + if (i == 0) + { + if (number.Kind != NumberBufferKind.FloatingPoint) + { + // The integer types don't have a concept of -0 and decimal always format -0 as 0 + number.IsNegative = false; + } + number.Scale = 0; // Decimals with scale ('0.00') should be rounded. + } + + dig[i] = (byte)('\0'); + number.DigitsCount = i; + number.CheckConsistency(); + + bool ShouldRoundUp(byte* _dig, int _i, NumberBufferKind numberKind, bool _isCorrectlyRounded) + { + // We only want to round up if the digit is greater than or equal to 5 and we are + // not rounding a floating-point number. If we are rounding a floating-point number + // we have one of two cases. + // + // In the case of a standard numeric-format specifier, the exact and correctly rounded + // string will have been produced. In this scenario, pos will have pointed to the + // terminating null for the buffer and so this will return false. + // + // However, in the case of a custom numeric-format specifier, we currently fall back + // to generating Single/DoublePrecisionCustomFormat digits and then rely on this + // function to round correctly instead. This can unfortunately lead to double-rounding + // bugs but is the best we have right now due to back-compat concerns. + + byte digit = _dig[_i]; + + if ((digit == '\0') || _isCorrectlyRounded) + { + // Fast path for the common case with no rounding + return false; + } + + // Values greater than or equal to 5 should round up, otherwise we round down. The IEEE + // 754 spec actually dictates that ties (exactly 5) should round to the nearest even number + // but that can have undesired behavior for custom numeric format strings. This probably + // needs further thought for .NET 5 so that we can be spec compliant and so that users + // can get the desired rounding behavior for their needs. + + return digit >= '5'; + } + } + + private static unsafe int FindSection(ReadOnlySpan format, int section) + { + int src; + char ch; + + if (section == 0) + return 0; + + fixed (char* pFormat = &MemoryMarshal.GetReference(format)) + { + src = 0; + while (true) + { + if (src >= format.Length) + { + return 0; + } + + switch (ch = pFormat[src++]) + { + case '\'': + case '"': + while (src < format.Length && pFormat[src] != 0 && pFormat[src++] != ch) ; + break; + case '\\': + if (src < format.Length && pFormat[src] != 0) + src++; + break; + case ';': + if (--section != 0) + break; + if (src < format.Length && pFormat[src] != 0 && pFormat[src] != ';') + return src; + goto case '\0'; + case '\0': + return 0; + } + } + } + } + + private static uint Low32(ulong value) => (uint)value; + + private static uint High32(ulong value) => (uint)((value & 0xFFFFFFFF00000000) >> 32); + + private static uint Int64DivMod1E9(ref ulong value) + { + uint rem = (uint)(value % 1000000000); + value /= 1000000000; + return rem; + } + + private static ulong ExtractFractionAndBiasedExponent(double value, out int exponent) + { + ulong bits = (ulong)(BitConverter.DoubleToInt64Bits(value)); + ulong fraction = (bits & 0xFFFFFFFFFFFFF); + exponent = ((int)(bits >> 52) & 0x7FF); + + if (exponent != 0) + { + // For normalized value, according to https://en.wikipedia.org/wiki/Double-precision_floating-point_format + // value = 1.fraction * 2^(exp - 1023) + // = (1 + mantissa / 2^52) * 2^(exp - 1023) + // = (2^52 + mantissa) * 2^(exp - 1023 - 52) + // + // So f = (2^52 + mantissa), e = exp - 1075; + + fraction |= (1UL << 52); + exponent -= 1075; + } + else + { + // For denormalized value, according to https://en.wikipedia.org/wiki/Double-precision_floating-point_format + // value = 0.fraction * 2^(1 - 1023) + // = (mantissa / 2^52) * 2^(-1022) + // = mantissa * 2^(-1022 - 52) + // = mantissa * 2^(-1074) + // So f = mantissa, e = -1074 + exponent = -1074; + } + + return fraction; + } + + private static uint ExtractFractionAndBiasedExponent(float value, out int exponent) + { + uint bits = (uint)(SingleToInt32Bits(value)); + uint fraction = (bits & 0x7FFFFF); + exponent = ((int)(bits >> 23) & 0xFF); + + if (exponent != 0) + { + // For normalized value, according to https://en.wikipedia.org/wiki/Single-precision_floating-point_format + // value = 1.fraction * 2^(exp - 127) + // = (1 + mantissa / 2^23) * 2^(exp - 127) + // = (2^23 + mantissa) * 2^(exp - 127 - 23) + // + // So f = (2^23 + mantissa), e = exp - 150; + + fraction |= (1U << 23); + exponent -= 150; + } + else + { + // For denormalized value, according to https://en.wikipedia.org/wiki/Single-precision_floating-point_format + // value = 0.fraction * 2^(1 - 127) + // = (mantissa / 2^23) * 2^(-126) + // = mantissa * 2^(-126 - 23) + // = mantissa * 2^(-149) + // So f = mantissa, e = -149 + exponent = -149; + } + + return fraction; + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/Number.Grisu3.cs b/src/ZString/Number/Number.Grisu3.cs new file mode 100644 index 00000000..49573aa2 --- /dev/null +++ b/src/ZString/Number/Number.Grisu3.cs @@ -0,0 +1,1067 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System +{ + internal static partial class Number + { + // This is a port of the `Grisu3` implementation here: https://github.com/google/double-conversion/blob/a711666ddd063eb1e4b181a6cb981d39a1fc8bac/double-conversion/fast-dtoa.cc + // The backing algorithm and the proofs behind it are described in more detail here: http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf + // ======================================================================================================================================== + // + // Overview: + // + // The general idea behind Grisu3 is to leverage additional bits and cached powers of ten to generate the correct digits. + // The algorithm is imprecise for some numbers. Fortunately, the algorithm itself can determine this scenario and gives us + // a result indicating success or failure. We must fallback to a different algorithm for the failing scenario. + internal static class Grisu3 + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe bool IsNegative(double d) + { + return BitConverter.DoubleToInt64Bits(d) < 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe bool IsNegativeInfinity(float f) + { + return f == float.NegativeInfinity; + } + + private const int CachedPowersDecimalExponentDistance = 8; + private const int CachedPowersMinDecimalExponent = -348; + private const int CachedPowersPowerMaxDecimalExponent = 340; + private const int CachedPowersOffset = -CachedPowersMinDecimalExponent; + + // 1 / Log2(10) + private const double D1Log210 = 0.301029995663981195; + + // The minimal and maximal target exponents define the range of w's binary exponent, + // where w is the result of multiplying the input by a cached power of ten. + // + // A different range might be chosen on a different platform, to optimize digit generation, + // but a smaller range requires more powers of ten to be cached. + private const int MaximalTargetExponent = -32; + private const int MinimalTargetExponent = -60; + + private static readonly short[] s_CachedPowersBinaryExponent = new short[] + { + -1220, + -1193, + -1166, + -1140, + -1113, + -1087, + -1060, + -1034, + -1007, + -980, + -954, + -927, + -901, + -874, + -847, + -821, + -794, + -768, + -741, + -715, + -688, + -661, + -635, + -608, + -582, + -555, + -529, + -502, + -475, + -449, + -422, + -396, + -369, + -343, + -316, + -289, + -263, + -236, + -210, + -183, + -157, + -130, + -103, + -77, + -50, + -24, + 3, + 30, + 56, + 83, + 109, + 136, + 162, + 189, + 216, + 242, + 269, + 295, + 322, + 348, + 375, + 402, + 428, + 455, + 481, + 508, + 534, + 561, + 588, + 614, + 641, + 667, + 694, + 720, + 747, + 774, + 800, + 827, + 853, + 880, + 907, + 933, + 960, + 986, + 1013, + 1039, + 1066, + }; + + private static readonly short[] s_CachedPowersDecimalExponent = new short[] + { + CachedPowersMinDecimalExponent, + -340, + -332, + -324, + -316, + -308, + -300, + -292, + -284, + -276, + -268, + -260, + -252, + -244, + -236, + -228, + -220, + -212, + -204, + -196, + -188, + -180, + -172, + -164, + -156, + -148, + -140, + -132, + -124, + -116, + -108, + -100, + -92, + -84, + -76, + -68, + -60, + -52, + -44, + -36, + -28, + -20, + -12, + -4, + 4, + 12, + 20, + 28, + 36, + 44, + 52, + 60, + 68, + 76, + 84, + 92, + 100, + 108, + 116, + 124, + 132, + 140, + 148, + 156, + 164, + 172, + 180, + 188, + 196, + 204, + 212, + 220, + 228, + 236, + 244, + 252, + 260, + 268, + 276, + 284, + 292, + 300, + 308, + 316, + 324, + 332, + CachedPowersPowerMaxDecimalExponent, + }; + + private static readonly ulong[] s_CachedPowersSignificand = new ulong[] + { + 0xFA8FD5A0081C0288, + 0xBAAEE17FA23EBF76, + 0x8B16FB203055AC76, + 0xCF42894A5DCE35EA, + 0x9A6BB0AA55653B2D, + 0xE61ACF033D1A45DF, + 0xAB70FE17C79AC6CA, + 0xFF77B1FCBEBCDC4F, + 0xBE5691EF416BD60C, + 0x8DD01FAD907FFC3C, + 0xD3515C2831559A83, + 0x9D71AC8FADA6C9B5, + 0xEA9C227723EE8BCB, + 0xAECC49914078536D, + 0x823C12795DB6CE57, + 0xC21094364DFB5637, + 0x9096EA6F3848984F, + 0xD77485CB25823AC7, + 0xA086CFCD97BF97F4, + 0xEF340A98172AACE5, + 0xB23867FB2A35B28E, + 0x84C8D4DFD2C63F3B, + 0xC5DD44271AD3CDBA, + 0x936B9FCEBB25C996, + 0xDBAC6C247D62A584, + 0xA3AB66580D5FDAF6, + 0xF3E2F893DEC3F126, + 0xB5B5ADA8AAFF80B8, + 0x87625F056C7C4A8B, + 0xC9BCFF6034C13053, + 0x964E858C91BA2655, + 0xDFF9772470297EBD, + 0xA6DFBD9FB8E5B88F, + 0xF8A95FCF88747D94, + 0xB94470938FA89BCF, + 0x8A08F0F8BF0F156B, + 0xCDB02555653131B6, + 0x993FE2C6D07B7FAC, + 0xE45C10C42A2B3B06, + 0xAA242499697392D3, + 0xFD87B5F28300CA0E, + 0xBCE5086492111AEB, + 0x8CBCCC096F5088CC, + 0xD1B71758E219652C, + 0x9C40000000000000, + 0xE8D4A51000000000, + 0xAD78EBC5AC620000, + 0x813F3978F8940984, + 0xC097CE7BC90715B3, + 0x8F7E32CE7BEA5C70, + 0xD5D238A4ABE98068, + 0x9F4F2726179A2245, + 0xED63A231D4C4FB27, + 0xB0DE65388CC8ADA8, + 0x83C7088E1AAB65DB, + 0xC45D1DF942711D9A, + 0x924D692CA61BE758, + 0xDA01EE641A708DEA, + 0xA26DA3999AEF774A, + 0xF209787BB47D6B85, + 0xB454E4A179DD1877, + 0x865B86925B9BC5C2, + 0xC83553C5C8965D3D, + 0x952AB45CFA97A0B3, + 0xDE469FBD99A05FE3, + 0xA59BC234DB398C25, + 0xF6C69A72A3989F5C, + 0xB7DCBF5354E9BECE, + 0x88FCF317F22241E2, + 0xCC20CE9BD35C78A5, + 0x98165AF37B2153DF, + 0xE2A0B5DC971F303A, + 0xA8D9D1535CE3B396, + 0xFB9B7CD9A4A7443C, + 0xBB764C4CA7A44410, + 0x8BAB8EEFB6409C1A, + 0xD01FEF10A657842C, + 0x9B10A4E5E9913129, + 0xE7109BFBA19C0C9D, + 0xAC2820D9623BF429, + 0x80444B5E7AA7CF85, + 0xBF21E44003ACDD2D, + 0x8E679C2F5E44FF8F, + 0xD433179D9C8CB841, + 0x9E19DB92B4E31BA9, + 0xEB96BF6EBADF77D9, + 0xAF87023B9BF0EE6B, + }; + + private static readonly uint[] s_SmallPowersOfTen = new uint[] + { + 1, // 10^0 + 10, // 10^1 + 100, // 10^2 + 1000, // 10^3 + 10000, // 10^4 + 100000, // 10^5 + 1000000, // 10^6 + 10000000, // 10^7 + 100000000, // 10^8 + 1000000000, // 10^9 + }; + + public static bool TryRunDouble(double value, int requestedDigits, ref NumberBuffer number) + { + double v = IsNegative(value) ? -value : value; + + Debug.Assert(v > 0); + //Debug.Assert(double.IsFinite(v)); + + int length; + int decimalExponent; + bool result; + + if (requestedDigits == -1) + { + DiyFp w = DiyFp.CreateAndGetBoundaries(v, out DiyFp boundaryMinus, out DiyFp boundaryPlus).Normalize(); + result = TryRunShortest(in boundaryMinus, in w, in boundaryPlus, number.Digits, out length, out decimalExponent); + } + else + { + DiyFp w = new DiyFp(v).Normalize(); + result = TryRunCounted(in w, requestedDigits, number.Digits, out length, out decimalExponent); + } + + if (result) + { + Debug.Assert((requestedDigits == -1) || (length == requestedDigits)); + + number.Scale = length + decimalExponent; + number.Digits[length] = (byte)('\0'); + number.DigitsCount = length; + } + + return result; + } + + public static bool TryRunSingle(float value, int requestedDigits, ref NumberBuffer number) + { + float v = IsNegative(value) ? -value : value; + + Debug.Assert(v > 0); + //Debug.Assert(float.IsFinite(v)); + + int length; + int decimalExponent; + bool result; + + if (requestedDigits == -1) + { + DiyFp w = DiyFp.CreateAndGetBoundaries(v, out DiyFp boundaryMinus, out DiyFp boundaryPlus).Normalize(); + result = TryRunShortest(in boundaryMinus, in w, in boundaryPlus, number.Digits, out length, out decimalExponent); + } + else + { + DiyFp w = new DiyFp(v).Normalize(); + result = TryRunCounted(in w, requestedDigits, number.Digits, out length, out decimalExponent); + } + + if (result) + { + Debug.Assert((requestedDigits == -1) || (length == requestedDigits)); + + number.Scale = length + decimalExponent; + number.Digits[length] = (byte)('\0'); + number.DigitsCount = length; + } + + return result; + } + + // The counted version of Grisu3 only generates requestedDigits number of digits. + // This version does not generate the shortest representation, and with enough requested digits 0.1 will at some point print as 0.9999999... + // Grisu3 is too imprecise for real halfway cases (1.5 will not work) and therefore the rounding strategy for halfway cases is irrelevant. + private static bool TryRunCounted(in DiyFp w, int requestedDigits, Span buffer, out int length, out int decimalExponent) + { + Debug.Assert(requestedDigits > 0); + + int tenMkMinimalBinaryExponent = MinimalTargetExponent - (w.e + DiyFp.SignificandSize); + int tenMkMaximalBinaryExponent = MaximalTargetExponent - (w.e + DiyFp.SignificandSize); + + DiyFp tenMk = GetCachedPowerForBinaryExponentRange(tenMkMinimalBinaryExponent, tenMkMaximalBinaryExponent, out int mk); + + Debug.Assert(MinimalTargetExponent <= (w.e + tenMk.e + DiyFp.SignificandSize)); + Debug.Assert(MaximalTargetExponent >= (w.e + tenMk.e + DiyFp.SignificandSize)); + + // Note that tenMk is only an approximation of 10^-k. + // A DiyFp only contains a 64-bit significand and tenMk is thus only precise up to 64-bits. + + // The DiyFp.Multiply procedure rounds its result and tenMk is approximated too. + // The variable scaledW (as well as scaledBoundaryMinus/Plus) are now off by a small amount. + // + // In fact, scaledW - (w * 10^k) < 1ulp (unit in last place) of scaledW. + // In other words, let f = scaledW.f and e = scaledW.e, then: + // (f - 1) * 2^e < (w * 10^k) < (f + 1) * 2^e + + DiyFp scaledW = w.Multiply(in tenMk); + + // We now have (double)(scaledW * 10^-mk). + // + // DigitGenCounted will generate the first requestedDigits of scaledW and return together with a kappa such that: + // scaledW ~= buffer * 10^kappa. + // + // It will not always be exactly the same since DigitGenCounted only produces a limited number of digits. + + bool result = TryDigitGenCounted(in scaledW, requestedDigits, buffer, out length, out int kappa); + decimalExponent = -mk + kappa; + return result; + } + + // Provides a decimal representation of v. + // Returns true if it succeeds; otherwise, the result cannot be trusted. + // + // There will be length digits inside the buffer (not null-terminated). + // If the function returns true then: + // v == (double)(buffer * 10^decimalExponent) + // + // The digits in the buffer are the shortest represenation possible (no 0.09999999999999999 instead of 0.1). + // The shorter representation will even be chosen if the longer one would be closer to v. + // + // The last digit will be closest to the actual v. + // That is, even if several digits might correctly yield 'v' when read again, the closest will be computed. + private static bool TryRunShortest(in DiyFp boundaryMinus, in DiyFp w, in DiyFp boundaryPlus, Span buffer, out int length, out int decimalExponent) + { + // boundaryMinus and boundaryPlus are the boundaries between v and its closest floating-point neighbors. + // Any number strictly between boundaryMinus and boundaryPlus will round to v when converted to a double. + // Grisu3 will never output representations that lie exactly on a boundary. + + Debug.Assert(boundaryPlus.e == w.e); + + int tenMkMinimalBinaryExponent = MinimalTargetExponent - (w.e + DiyFp.SignificandSize); + int tenMkMaximalBinaryExponent = MaximalTargetExponent - (w.e + DiyFp.SignificandSize); + + DiyFp tenMk = GetCachedPowerForBinaryExponentRange(tenMkMinimalBinaryExponent, tenMkMaximalBinaryExponent, out int mk); + + Debug.Assert(MinimalTargetExponent <= (w.e + tenMk.e + DiyFp.SignificandSize)); + Debug.Assert(MaximalTargetExponent >= (w.e + tenMk.e + DiyFp.SignificandSize)); + + // Note that tenMk is only an approximation of 10^-k. + // A DiyFp only contains a 64-bit significan and tenMk is thus only precise up to 64-bits. + + // The DiyFp.Multiply procedure rounds its result and tenMk is approximated too. + // The variable scaledW (as well as scaledBoundaryMinus/Plus) are now off by a small amount. + // + // In fact, scaledW - (w * 10^k) < 1ulp (unit in last place) of scaledW. + // In other words, let f = scaledW.f and e = scaledW.e, then: + // (f - 1) * 2^e < (w * 10^k) < (f + 1) * 2^e + + DiyFp scaledW = w.Multiply(in tenMk); + Debug.Assert(scaledW.e == (boundaryPlus.e + tenMk.e + DiyFp.SignificandSize)); + + // In theory, it would be possible to avoid some recomputations by computing the difference between w + // and boundaryMinus/Plus (a power of 2) and to compute scaledBoundaryMinus/Plus by subtracting/adding + // from scaledW. However, the code becomes much less readable and the speed enhancements are not terrific. + + DiyFp scaledBoundaryMinus = boundaryMinus.Multiply(in tenMk); + DiyFp scaledBoundaryPlus = boundaryPlus.Multiply(in tenMk); + + // DigitGen will generate the digits of scaledW. Therefore, we have: + // v == (double)(scaledW * 10^-mk) + // + // Set decimalExponent == -mk and pass it to DigitGen and if scaledW is not an integer than it will be updated. + // For instance, if scaledW == 1.23 then the buffer will be filled with "123" and the decimalExponent will be decreased by 2. + + bool result = TryDigitGenShortest(in scaledBoundaryMinus, in scaledW, in scaledBoundaryPlus, buffer, out length, out int kappa); + decimalExponent = -mk + kappa; + return result; + } + + // Returns the biggest power of ten that is less than or equal to the given number. + // We furthermore receive the maximum number of bits 'number' has. + // + // Returns power == 10^(exponent) such that + // power <= number < power * 10 + // If numberBits == 0, then 0^(0-1) is returned. + // The number of bits must be <= 32. + // + // Preconditions: + // number < (1 << (numberBits + 1)) + private static uint BiggestPowerTen(uint number, int numberBits, out int exponentPlusOne) + { + // Inspired by the method for finding an integer log base 10 from here: + // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 + + Debug.Assert(number < (1U << (numberBits + 1))); + + // 1233/4096 is approximately 1/log2(10) + int exponentGuess = ((numberBits + 1) * 1233) >> 12; + Debug.Assert((uint)(exponentGuess) < s_SmallPowersOfTen.Length); + + uint power = s_SmallPowersOfTen[exponentGuess]; + + // We don't have any guarantees that 2^numberBits <= number + if (number < power) + { + exponentGuess--; + power = s_SmallPowersOfTen[exponentGuess]; + } + + exponentPlusOne = exponentGuess + 1; + return power; + } + + // Generates (at most) requestedDigits of input number w. + // + // w is a floating-point number (DiyFp), consisting of a significand and an exponent. + // Its exponent is bounded by MinimalTargetExponent and MaximalTargetExponent, hence: + // -60 <= w.e <= -32 + // + // Returns false if it fails, in which case the generated digits in the buffer should not be used. + // + // Preconditions: + // w is correct up to 1 ulp (unit in last place). That is, its error must be strictly less than a unit of its last digit. + // MinimalTargetExponent <= w.e <= MaximalTargetExponent + // + // Postconditions: + // Returns false if the procedure fails; otherwise: + // * buffer is not null-terminated, but length contains the number of digits. + // * The representation in buffer is the most precise representation of requestedDigits digits. + // * buffer contains at most requestedDigits digits of w. If there are less than requestedDigits digits then some trailing '0's have been removed. + // * kappa is such that w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2. + // + // This procedure takes into account the imprecision of its input numbers. + // If the precision is not enough to guarantee all the postconditions, then false is returned. + // This usually happens rarely, but the failure-rate increases with higher requestedDigits + private static bool TryDigitGenCounted(in DiyFp w, int requestedDigits, Span buffer, out int length, out int kappa) + { + Debug.Assert(MinimalTargetExponent <= w.e); + Debug.Assert(w.e <= MaximalTargetExponent); + Debug.Assert(MinimalTargetExponent >= -60); + Debug.Assert(MaximalTargetExponent <= -32); + + // w is assumed to have an error less than 1 unit. + // Whenever w is scaled we also scale its error. + ulong wError = 1; + + // We cut the input number into two parts: the integral digits and the fractional digits. + // We don't emit any decimal separator, but adapt kapp instead. + // For example: instead of writing "1.2", we put "12" into the buffer and increase kappa by 1. + var one = new DiyFp(1UL << -w.e, w.e); + + // Division by one is a shift. + uint integrals = (uint)(w.f >> -one.e); + + // Modulo by one is an and. + ulong fractionals = w.f & (one.f - 1); + + // We deviate from the original algorithm here and do some early checks to determine if we can satisfy requestedDigits. + // If we determine that we can't, we exit early and avoid most of the heavy lifting that the algorithm otherwise does. + // + // When fractionals is zero, we can easily determine if integrals can satisfy requested digits: + // If requestedDigits >= 11, integrals is not able to exhaust the count by itself since 10^(11 -1) > uint.MaxValue >= integrals. + // If integrals < 10^(requestedDigits - 1), integrals cannot exhaust the count. + // Otherwise, integrals might be able to exhaust the count and we need to execute the rest of the code. + if ((fractionals == 0) && ((requestedDigits >= 11) || (integrals < s_SmallPowersOfTen[requestedDigits - 1]))) + { + Debug.Assert(buffer[0] == '\0'); + length = 0; + kappa = 0; + return false; + } + + uint divisor = BiggestPowerTen(integrals, DiyFp.SignificandSize - (-one.e), out kappa); + length = 0; + + // Loop invariant: + // buffer = w / 10^kappa (integer division) + // These invariants hold for the first iteration: + // kappa has been initialized with the divisor exponent + 1 + // The divisor is the biggest power of ten that is smaller than integrals + while (kappa > 0) + { + uint digit = MathEx.DivRem(integrals, divisor, out integrals); + Debug.Assert(digit <= 9); + buffer[length] = (byte)('0' + digit); + + length++; + requestedDigits--; + kappa--; + + // Note that kappa now equals the exponent of the + // divisor and that the invariant thus holds again. + if (requestedDigits == 0) + { + break; + } + + divisor /= 10; + } + + if (requestedDigits == 0) + { + ulong rest = ((ulong)(integrals) << -one.e) + fractionals; + return TryRoundWeedCounted( + buffer, + length, + rest, + tenKappa: ((ulong)(divisor)) << -one.e, + unit: wError, + ref kappa + ); + } + + // The integrals have been generated and we are at the point of the decimal separator. + // In the following loop, we simply multiply the remaining digits by 10 and divide by one. + // We just need to pay attention to multiply associated data (the unit), too. + // Note that the multiplication by 10 does not overflow because: + // w.e >= -60 and thus one.e >= -60 + + Debug.Assert(one.e >= MinimalTargetExponent); + Debug.Assert(fractionals < one.f); + Debug.Assert((ulong.MaxValue / 10) >= one.f); + + while ((requestedDigits > 0) && (fractionals > wError)) + { + fractionals *= 10; + wError *= 10; + + // Integer division by one. + uint digit = (uint)(fractionals >> -one.e); + Debug.Assert(digit <= 9); + buffer[length] = (byte)('0' + digit); + + length++; + requestedDigits--; + kappa--; + + // Modulo by one. + fractionals &= (one.f - 1); + } + + if (requestedDigits != 0) + { + buffer[0] = (byte)('\0'); + length = 0; + kappa = 0; + return false; + } + + return TryRoundWeedCounted( + buffer, + length, + rest: fractionals, + tenKappa: one.f, + unit: wError, + ref kappa + ); + } + + // Generates the digits of input number w. + // + // w is a floating-point number (DiyFp), consisting of a significand and an exponent. + // Its exponent is bounded by kMinimalTargetExponent and kMaximalTargetExponent, hence: + // -60 <= w.e() <= -32. + // + // Returns false if it fails, in which case the generated digits in the buffer should not be used. + // + // Preconditions: + // low, w and high are correct up to 1 ulp (unit in the last place). That is, their error must be less than a unit of their last digits. + // low.e() == w.e() == high.e() + // low < w < high, and taking into account their error: low~ <= high~ + // kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent + // + // Postconditions: + // Returns false if procedure fails; otherwise: + // * buffer is not null-terminated, but len contains the number of digits. + // * buffer contains the shortest possible decimal digit-sequence such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the correct values of low and high (without their error). + // * If more than one decimal representation gives the minimal number of decimal digits then the one closest to W (where W is the correct value of w) is chosen. + // + // This procedure takes into account the imprecision of its input numbers. + // If the precision is not enough to guarantee all the postconditions then false is returned. + // This usually happens rarely (~0.5%). + // + // Say, for the sake of example, that: + // w.e() == -48, and w.f() == 0x1234567890abcdef + // + // w's value can be computed by w.f() * 2^w.e() + // + // We can obtain w's integral digits by simply shifting w.f() by -w.e(). + // -> w's integral part is 0x1234 + // w's fractional part is therefore 0x567890abcdef. + // + // Printing w's integral part is easy (simply print 0x1234 in decimal). + // + // In order to print its fraction we repeatedly multiply the fraction by 10 and get each digit. + // For example, the first digit after the point would be computed by + // (0x567890abcdef * 10) >> 48. -> 3 + // + // The whole thing becomes slightly more complicated because we want to stop once we have enough digits. + // That is, once the digits inside the buffer represent 'w' we can stop. + // + // Everything inside the interval low - high represents w. + // However we have to pay attention to low, high and w's imprecision. + private static bool TryDigitGenShortest(in DiyFp low, in DiyFp w, in DiyFp high, Span buffer, out int length, out int kappa) + { + Debug.Assert(low.e == w.e); + Debug.Assert(w.e == high.e); + + Debug.Assert((low.f + 1) <= (high.f - 1)); + + Debug.Assert(MinimalTargetExponent <= w.e); + Debug.Assert(w.e <= MaximalTargetExponent); + + // low, w, and high are imprecise, but by less than one ulp (unit in the last place). + // + // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that the new numbers + // are outside of the interval we want the final representation to lie in. + // + // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield numbers that + // are certain to lie in the interval. We will use this fact later on. + // + // We will now start by generating the digits within the uncertain interval. + // Later, we will weed out representations that lie outside the safe interval and thus might lie outside the correct interval. + + ulong unit = 1; + + var tooLow = new DiyFp(low.f - unit, low.e); + var tooHigh = new DiyFp(high.f + unit, high.e); + + // tooLow and tooHigh are guaranteed to lie outside the interval we want the generated number in. + + DiyFp unsafeInterval = tooHigh.Subtract(in tooLow); + + // We now cut the input number into two parts: the integral digits and the fractional digits. + // We will not write any decimal separator, but adapt kappa instead. + // + // Reminder: we are currently computing the digits (Stored inside the buffer) such that: + // tooLow < buffer * 10^kappa < tooHigh + // + // We use tooHigh for the digitGeneration and stop as soon as possible. + // If we stop early, we effectively round down. + + var one = new DiyFp(1UL << -w.e, w.e); + + // Division by one is a shift. + uint integrals = (uint)(tooHigh.f >> -one.e); + + // Modulo by one is an and. + ulong fractionals = tooHigh.f & (one.f - 1); + + uint divisor = BiggestPowerTen(integrals, DiyFp.SignificandSize - (-one.e), out kappa); + length = 0; + + // Loop invariant: + // buffer = tooHigh / 10^kappa (integer division) + // These invariants hold for the first iteration: + // kappa has been initialized with the divisor exponent + 1 + // The divisor is the biggest power of ten that is smaller than integrals + while (kappa > 0) + { + uint digit = MathEx.DivRem(integrals, divisor, out integrals); + Debug.Assert(digit <= 9); + buffer[length] = (byte)('0' + digit); + + length++; + kappa--; + + // Note that kappa now equals the exponent of the + // divisor and that the invariant thus holds again. + + ulong rest = ((ulong)(integrals) << -one.e) + fractionals; + + // Invariant: tooHigh = buffer * 10^kappa + DiyFp(rest, one.e) + // Reminder: unsafeInterval.e == one.e + + if (rest < unsafeInterval.f) + { + // Rounding down (by not emitting the remaining digits) + // yields a number that lies within the unsafe interval + + return TryRoundWeedShortest( + buffer, + length, + tooHigh.Subtract(w).f, + unsafeInterval.f, + rest, + tenKappa: ((ulong)(divisor)) << -one.e, + unit + ); + } + + divisor /= 10; + } + + // The integrals have been generated and we are at the point of the decimal separator. + // In the following loop, we simply multiply the remaining digits by 10 and divide by one. + // We just need to pay attention to multiply associated data (the unit), too. + // Note that the multiplication by 10 does not overflow because: + // w.e >= -60 and thus one.e >= -60 + + Debug.Assert(one.e >= MinimalTargetExponent); + Debug.Assert(fractionals < one.f); + Debug.Assert((ulong.MaxValue / 10) >= one.f); + + while (true) + { + fractionals *= 10; + unit *= 10; + + unsafeInterval = new DiyFp(unsafeInterval.f * 10, unsafeInterval.e); + + // Integer division by one. + uint digit = (uint)(fractionals >> -one.e); + Debug.Assert(digit <= 9); + buffer[length] = (byte)('0' + digit); + + length++; + kappa--; + + // Modulo by one. + fractionals &= (one.f - 1); + + if (fractionals < unsafeInterval.f) + { + return TryRoundWeedShortest( + buffer, + length, + tooHigh.Subtract(w).f * unit, + unsafeInterval.f, + rest: fractionals, + tenKappa: one.f, + unit + ); + } + } + } + + // Returns a cached power-of-ten with a binary exponent in the range [minExponent; maxExponent] (boundaries included). + private static DiyFp GetCachedPowerForBinaryExponentRange(int minExponent, int maxExponent, out int decimalExponent) + { + Debug.Assert(s_CachedPowersSignificand.Length == s_CachedPowersBinaryExponent.Length); + Debug.Assert(s_CachedPowersSignificand.Length == s_CachedPowersDecimalExponent.Length); + + double k = Math.Ceiling((minExponent + DiyFp.SignificandSize - 1) * D1Log210); + int index = ((CachedPowersOffset + (int)(k) - 1) / CachedPowersDecimalExponentDistance) + 1; + + Debug.Assert((uint)(index) < s_CachedPowersSignificand.Length); + + Debug.Assert(minExponent <= s_CachedPowersBinaryExponent[index]); + Debug.Assert(s_CachedPowersBinaryExponent[index] <= maxExponent); + + decimalExponent = s_CachedPowersDecimalExponent[index]; + return new DiyFp(s_CachedPowersSignificand[index], s_CachedPowersBinaryExponent[index]); + } + + // Rounds the buffer upwards if the result is closer to v by possibly adding 1 to the buffer. + // If the precision of the calculation is not sufficient to round correctly, return false. + // + // The rounding might shift the whole buffer, in which case, the kappy is adjusted. + // For example "99", kappa = 3 might become "10", kappa = 4. + // + // If (2 * rest) > tenKappa then the buffer needs to be round up. + // rest can have an error of +/- 1 unit. + // This function accounts for the imprecision and returns false if the rounding direction cannot be unambiguously determined. + // + // Preconditions: + // rest < tenKappa + private static bool TryRoundWeedCounted(Span buffer, int length, ulong rest, ulong tenKappa, ulong unit, ref int kappa) + { + Debug.Assert(rest < tenKappa); + + // The following tests are done in a specific order to avoid overflows. + // They will work correctly with any ulong values of rest < tenKappa and unit. + // + // If the unit is too big, then we don't know which way to round. + // For example, a unit of 50 means that the real number lies within rest +/- 50. + // If 10^kappa == 40, then there is no way to tell which way to round. + // + // Even if unit is just half the size of 10^kappa we are already completely lost. + // And after the previous test, we know that the expression will not over/underflow. + if ((unit >= tenKappa) || ((tenKappa - unit) <= unit)) + { + return false; + } + + // If 2 * (rest + unit) <= 10^kappa, we can safely round down. + if (((tenKappa - rest) > rest) && ((tenKappa - (2 * rest)) >= (2 * unit))) + { + return true; + } + + // If 2 * (rest - unit) >= 10^kappa, we can safely round up. + if ((rest > unit) && (tenKappa <= (rest - unit) || ((tenKappa - (rest - unit)) <= (rest - unit)))) + { + // Increment the last digit recursively until we find a non '9' digit. + buffer[length - 1]++; + + for (int i = (length - 1); i > 0; i--) + { + if (buffer[i] != ('0' + 10)) + { + break; + } + + buffer[i] = (byte)('0'); + buffer[i - 1]++; + } + + // If the first digit is now '0'+10, we had a buffer with all '9's. + // With the exception of the first digit, all digits are now '0'. + // Simply switch the first digit to '1' and adjust the kappa. + // For example, "99" becomes "10" and the power (the kappa) is increased. + if (buffer[0] == ('0' + 10)) + { + buffer[0] = (byte)('1'); + kappa++; + } + + return true; + } + + return false; + } + + // Adjusts the last digit of the generated number and screens out generated solutions that may be inaccurate. + // A solution may be inaccurate if it is outside the safe interval or if we cannot provide that it is closer to the input than a neighboring representation of the same length. + // + // Input: + // buffer containing the digits of tooHigh / 10^kappa + // the buffer's length + // distanceTooHighW == (tooHigh - w).f * unit + // unsafeInterval == (tooHigh - tooLow).f * unit + // rest = (tooHigh - buffer * 10^kapp).f * unit + // tenKappa = 10^kappa * unit + // unit = the common multiplier + // + // Output: + // Returns true if the buffer is guaranteed to contain the closest representable number to the input. + // + // Modifies the generated digits in the buffer to approach (round towards) w. + private static bool TryRoundWeedShortest(Span buffer, int length, ulong distanceTooHighW, ulong unsafeInterval, ulong rest, ulong tenKappa, ulong unit) + { + ulong smallDistance = distanceTooHighW - unit; + ulong bigDistance = distanceTooHighW + unit; + + // Let wLow = tooHigh - bigDistance, and wHigh = tooHigh - smallDistance. + // + // Note: wLow < w < wHigh + // + // The real w * unit must lie somewhere inside the interval + // ]w_low; w_high[ (often written as "(w_low; w_high)") + + // Basically the buffer currently contains a number in the unsafe interval + // ]too_low; too_high[ with too_low < w < too_high + // + // tooHigh - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ^v 1 unit ^ ^ ^ ^ + // boundaryHigh --------------------- . . . . + // ^v 1 unit . . . . + // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . + // . . ^ . . + // . bigDistance . . . + // . . . . rest + // smallDistance . . . . + // v . . . . + // wHigh - - - - - - - - - - - - - - - - - - . . . . + // ^v 1 unit . . . . + // w --------------------------------------- . . . . + // ^v 1 unit v . . . + // wLow - - - - - - - - - - - - - - - - - - - - - . . . + // . . v + // buffer -------------------------------------------------+-------+-------- + // . . + // safeInterval . + // v . + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . + // ^v 1 unit . + // boundaryLow ------------------------- unsafeInterval + // ^v 1 unit v + // tooLow - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // + // Note that the value of buffer could lie anywhere inside the range tooLow to tooHigh. + // + // boundaryLow, boundaryHigh and w are approximations of the real boundaries and v (the input number). + // They are guaranteed to be precise up to one unit. + // In fact the error is guaranteed to be strictly less than one unit. + // + // Anything that lies outside the unsafe interval is guaranteed not to round to v when read again. + // Anything that lies inside the safe interval is guaranteed to round to v when read again. + // + // If the number inside the buffer lies inside the unsafe interval but not inside the safe interval + // then we simply do not know and bail out (returning false). + // + // Similarly we have to take into account the imprecision of 'w' when finding the closest representation of 'w'. + // If we have two potential representations, and one is closer to both wLow and wHigh, then we know it is closer to the actual value v. + // + // By generating the digits of tooHigh we got the largest (closest to tooHigh) buffer that is still in the unsafe interval. + // In the case where wHigh < buffer < tooHigh we try to decrement the buffer. + // This way the buffer approaches (rounds towards) w. + // + // There are 3 conditions that stop the decrementation process: + // 1) the buffer is already below wHigh + // 2) decrementing the buffer would make it leave the unsafe interval + // 3) decrementing the buffer would yield a number below wHigh and farther away than the current number. + // + // In other words: + // (buffer{-1} < wHigh) && wHigh - buffer{-1} > buffer - wHigh + // + // Instead of using the buffer directly we use its distance to tooHigh. + // + // Conceptually rest ~= tooHigh - buffer + // + // We need to do the following tests in this order to avoid over- and underflows. + + Debug.Assert(rest <= unsafeInterval); + + while ((rest < smallDistance) && ((unsafeInterval - rest) >= tenKappa) && (((rest + tenKappa) < smallDistance) || ((smallDistance - rest) >= (rest + tenKappa - smallDistance)))) + { + buffer[length - 1]--; + rest += tenKappa; + } + + // We have approached w+ as much as possible. + // We now test if approaching w- would require changing the buffer. + // If yes, then we have two possible representations close to w, but we cannot decide which one is closer. + if ((rest < bigDistance) && ((unsafeInterval - rest) >= tenKappa) && (((rest + tenKappa) < bigDistance) || ((bigDistance - rest) > (rest + tenKappa - bigDistance)))) + { + return false; + } + + // Weeding test. + // + // The safe interval is [tooLow + 2 ulp; tooHigh - 2 ulp] + // Since tooLow = tooHigh - unsafeInterval this is equivalent to + // [tooHigh - unsafeInterval + 4 ulp; tooHigh - 2 ulp] + // + // Conceptually we have: rest ~= tooHigh - buffer + return ((2 * unit) <= rest) && (rest <= (unsafeInterval - 4 * unit)); + } + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/Number.NumberBuffer.cs b/src/ZString/Number/Number.NumberBuffer.cs new file mode 100644 index 00000000..b9350468 --- /dev/null +++ b/src/ZString/Number/Number.NumberBuffer.cs @@ -0,0 +1,124 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Text; + +namespace System +{ + internal static partial class Number + { + // We need 1 additional byte, per length, for the terminating null + internal const int DecimalNumberBufferLength = 29 + 1 + 1; // 29 for the longest input + 1 for rounding + internal const int DoubleNumberBufferLength = 767 + 1 + 1; // 767 for the longest input + 1 for rounding: 4.9406564584124654E-324 + internal const int Int32NumberBufferLength = 10 + 1; // 10 for the longest input: 2,147,483,647 + internal const int Int64NumberBufferLength = 19 + 1; // 19 for the longest input: 9,223,372,036,854,775,807 + internal const int SingleNumberBufferLength = 112 + 1 + 1; // 112 for the longest input + 1 for rounding: 1.40129846E-45 + internal const int UInt32NumberBufferLength = 10 + 1; // 10 for the longest input: 4,294,967,295 + internal const int UInt64NumberBufferLength = 20 + 1; // 20 for the longest input: 18,446,744,073,709,551,615 + + internal unsafe ref struct NumberBuffer + { + public int DigitsCount; + public int Scale; + public bool IsNegative; + public bool HasNonZeroTail; + public NumberBufferKind Kind; + public Span Digits; + + public NumberBuffer(NumberBufferKind kind, byte* digits, int digitsLength) + { + Debug.Assert(digits != null); + Debug.Assert(digitsLength > 0); + + DigitsCount = 0; + Scale = 0; + IsNegative = false; + HasNonZeroTail = false; + Kind = kind; + Digits = new Span(digits, digitsLength); + +#if DEBUG + Digits.Fill(0xCC); +#endif + + Digits[0] = (byte)('\0'); + CheckConsistency(); + } + + [Conditional("DEBUG")] + public void CheckConsistency() + { +#if DEBUG + Debug.Assert((Kind == NumberBufferKind.Integer) || (Kind == NumberBufferKind.Decimal) || (Kind == NumberBufferKind.FloatingPoint)); + Debug.Assert(Digits[0] != '0', "Leading zeros should never be stored in a Number"); + + int numDigits; + for (numDigits = 0; numDigits < Digits.Length; numDigits++) + { + byte digit = Digits[numDigits]; + + if (digit == 0) + { + break; + } + + Debug.Assert((digit >= '0') && (digit <= '9'), "Unexpected character found in Number"); + } + + Debug.Assert(numDigits == DigitsCount, "Null terminator found in unexpected location in Number"); + Debug.Assert(numDigits < Digits.Length, "Null terminator not found in Number"); +#endif // DEBUG + } + + public byte* GetDigitsPointer() + { + // This is safe to do since we are a ref struct + return (byte*)(Unsafe.AsPointer(ref Digits[0])); + } + + // + // Code coverage note: This only exists so that Number displays nicely in the VS watch window. So yes, I know it works. + // + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append('['); + sb.Append('"'); + + for (int i = 0; i < Digits.Length; i++) + { + byte digit = Digits[i]; + + if (digit == 0) + { + break; + } + + sb.Append((char)(digit)); + } + + sb.Append('"'); + sb.Append(", Length = ").Append(DigitsCount); + sb.Append(", Scale = ").Append(Scale); + sb.Append(", IsNegative = ").Append(IsNegative); + sb.Append(", HasNonZeroTail = ").Append(HasNonZeroTail); + sb.Append(", Kind = ").Append(Kind); + sb.Append(']'); + + return sb.ToString(); + } + } + + internal enum NumberBufferKind : byte + { + Unknown = 0, + Integer = 1, + Decimal = 2, + FloatingPoint = 3, + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/Number.NumberToFloatingPointBits.cs b/src/ZString/Number/Number.NumberToFloatingPointBits.cs new file mode 100644 index 00000000..d0bf894c --- /dev/null +++ b/src/ZString/Number/Number.NumberToFloatingPointBits.cs @@ -0,0 +1,637 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System +{ + internal unsafe partial class Number + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe int SingleToInt32Bits(float value) + { + return *((int*)&value); + } + + public readonly struct FloatingPointInfo + { + public static readonly FloatingPointInfo Double = new FloatingPointInfo( + denormalMantissaBits: 52, + exponentBits: 11, + maxBinaryExponent: 1023, + exponentBias: 1023, + infinityBits: 0x7FF00000_00000000 + ); + + public static readonly FloatingPointInfo Single = new FloatingPointInfo( + denormalMantissaBits: 23, + exponentBits: 8, + maxBinaryExponent: 127, + exponentBias: 127, + infinityBits: 0x7F800000 + ); + + public ulong ZeroBits { get; } + public ulong InfinityBits { get; } + + public ulong NormalMantissaMask { get; } + public ulong DenormalMantissaMask { get; } + + public int MinBinaryExponent { get; } + public int MaxBinaryExponent { get; } + + public int ExponentBias { get; } + public int OverflowDecimalExponent { get; } + + public ushort NormalMantissaBits { get; } + public ushort DenormalMantissaBits { get; } + + public ushort ExponentBits { get; } + + public FloatingPointInfo(ushort denormalMantissaBits, ushort exponentBits, int maxBinaryExponent, int exponentBias, ulong infinityBits) + { + ExponentBits = exponentBits; + + DenormalMantissaBits = denormalMantissaBits; + NormalMantissaBits = (ushort)(denormalMantissaBits + 1); // we get an extra (hidden) bit for normal mantissas + + OverflowDecimalExponent = (maxBinaryExponent + 2 * NormalMantissaBits) / 3; + ExponentBias = exponentBias; + + MaxBinaryExponent = maxBinaryExponent; + MinBinaryExponent = 1 - maxBinaryExponent; + + DenormalMantissaMask = (1UL << denormalMantissaBits) - 1; + NormalMantissaMask = (1UL << NormalMantissaBits) - 1; + + InfinityBits = infinityBits; + ZeroBits = 0; + } + } + + private static readonly float[] s_Pow10SingleTable = new float[] + { + 1e0f, // 10^0 + 1e1f, // 10^1 + 1e2f, // 10^2 + 1e3f, // 10^3 + 1e4f, // 10^4 + 1e5f, // 10^5 + 1e6f, // 10^6 + 1e7f, // 10^7 + 1e8f, // 10^8 + 1e9f, // 10^9 + 1e10f, // 10^10 + }; + + private static readonly double[] s_Pow10DoubleTable = new double[] + { + 1e0, // 10^0 + 1e1, // 10^1 + 1e2, // 10^2 + 1e3, // 10^3 + 1e4, // 10^4 + 1e5, // 10^5 + 1e6, // 10^6 + 1e7, // 10^7 + 1e8, // 10^8 + 1e9, // 10^9 + 1e10, // 10^10 + 1e11, // 10^11 + 1e12, // 10^12 + 1e13, // 10^13 + 1e14, // 10^14 + 1e15, // 10^15 + 1e16, // 10^16 + 1e17, // 10^17 + 1e18, // 10^18 + 1e19, // 10^19 + 1e20, // 10^20 + 1e21, // 10^21 + 1e22, // 10^22 + }; + + private static void AccumulateDecimalDigitsIntoBigInteger(ref NumberBuffer number, uint firstIndex, uint lastIndex, out BigInteger result) + { + BigInteger.SetZero(out result); + + byte* src = number.GetDigitsPointer() + firstIndex; + uint remaining = lastIndex - firstIndex; + + while (remaining != 0) + { + uint count = Math.Min(remaining, 9); + uint value = DigitsToUInt32(src, (int)(count)); + + result.MultiplyPow10(count); + result.Add(value); + + src += count; + remaining -= count; + } + } + + private static ulong AssembleFloatingPointBits(in FloatingPointInfo info, ulong initialMantissa, int initialExponent, bool hasZeroTail) + { + // number of bits by which we must adjust the mantissa to shift it into the + // correct position, and compute the resulting base two exponent for the + // normalized mantissa: + uint initialMantissaBits = BigInteger.CountSignificantBits(initialMantissa); + int normalMantissaShift = info.NormalMantissaBits - (int)(initialMantissaBits); + int normalExponent = initialExponent - normalMantissaShift; + + ulong mantissa = initialMantissa; + int exponent = normalExponent; + + if (normalExponent > info.MaxBinaryExponent) + { + // The exponent is too large to be represented by the floating point + // type; report the overflow condition: + return info.InfinityBits; + } + else if (normalExponent < info.MinBinaryExponent) + { + // The exponent is too small to be represented by the floating point + // type as a normal value, but it may be representable as a denormal + // value. Compute the number of bits by which we need to shift the + // mantissa in order to form a denormal number. (The subtraction of + // an extra 1 is to account for the hidden bit of the mantissa that + // is not available for use when representing a denormal.) + int denormalMantissaShift = normalMantissaShift + normalExponent + info.ExponentBias - 1; + + // Denormal values have an exponent of zero, so the debiased exponent is + // the negation of the exponent bias: + exponent = -info.ExponentBias; + + if (denormalMantissaShift < 0) + { + // Use two steps for right shifts: for a shift of N bits, we first + // shift by N-1 bits, then shift the last bit and use its value to + // round the mantissa. + mantissa = RightShiftWithRounding(mantissa, -denormalMantissaShift, hasZeroTail); + + // If the mantissa is now zero, we have underflowed: + if (mantissa == 0) + { + return info.ZeroBits; + } + + // When we round the mantissa, the result may be so large that the + // number becomes a normal value. For example, consider the single + // precision case where the mantissa is 0x01ffffff and a right shift + // of 2 is required to shift the value into position. We perform the + // shift in two steps: we shift by one bit, then we shift again and + // round using the dropped bit. The initial shift yields 0x00ffffff. + // The rounding shift then yields 0x007fffff and because the least + // significant bit was 1, we add 1 to this number to round it. The + // final result is 0x00800000. + // + // 0x00800000 is 24 bits, which is more than the 23 bits available + // in the mantissa. Thus, we have rounded our denormal number into + // a normal number. + // + // We detect this case here and re-adjust the mantissa and exponent + // appropriately, to form a normal number: + if (mantissa > info.DenormalMantissaMask) + { + // We add one to the denormal_mantissa_shift to account for the + // hidden mantissa bit (we subtracted one to account for this bit + // when we computed the denormal_mantissa_shift above). + exponent = initialExponent - (denormalMantissaShift + 1) - normalMantissaShift; + } + } + else + { + mantissa <<= denormalMantissaShift; + } + } + else + { + if (normalMantissaShift < 0) + { + // Use two steps for right shifts: for a shift of N bits, we first + // shift by N-1 bits, then shift the last bit and use its value to + // round the mantissa. + mantissa = RightShiftWithRounding(mantissa, -normalMantissaShift, hasZeroTail); + + // When we round the mantissa, it may produce a result that is too + // large. In this case, we divide the mantissa by two and increment + // the exponent (this does not change the value). + if (mantissa > info.NormalMantissaMask) + { + mantissa >>= 1; + exponent++; + + // The increment of the exponent may have generated a value too + // large to be represented. In this case, report the overflow: + if (exponent > info.MaxBinaryExponent) + { + return info.InfinityBits; + } + } + } + else if (normalMantissaShift > 0) + { + mantissa <<= normalMantissaShift; + } + } + + // Unset the hidden bit in the mantissa and assemble the floating point value + // from the computed components: + mantissa &= info.DenormalMantissaMask; + + Debug.Assert((info.DenormalMantissaMask & (1UL << info.DenormalMantissaBits)) == 0); + ulong shiftedExponent = ((ulong)(exponent + info.ExponentBias)) << info.DenormalMantissaBits; + Debug.Assert((shiftedExponent & info.DenormalMantissaMask) == 0); + Debug.Assert((mantissa & ~info.DenormalMantissaMask) == 0); + Debug.Assert((shiftedExponent & ~(((1UL << info.ExponentBits) - 1) << info.DenormalMantissaBits)) == 0); // exponent fits in its place + + return shiftedExponent | mantissa; + } + + private static ulong ConvertBigIntegerToFloatingPointBits(ref BigInteger value, in FloatingPointInfo info, uint integerBitsOfPrecision, bool hasNonZeroFractionalPart) + { + int baseExponent = info.DenormalMantissaBits; + + // When we have 64-bits or less of precision, we can just get the mantissa directly + if (integerBitsOfPrecision <= 64) + { + return AssembleFloatingPointBits(in info, value.ToUInt64(), baseExponent, !hasNonZeroFractionalPart); + } + + uint topBlockIndex = MathEx.DivRem(integerBitsOfPrecision, 32, out uint topBlockBits); + uint middleBlockIndex = topBlockIndex - 1; + uint bottomBlockIndex = middleBlockIndex - 1; + + ulong mantissa; + int exponent = baseExponent + ((int)(bottomBlockIndex) * 32); + bool hasZeroTail = !hasNonZeroFractionalPart; + + // When the top 64-bits perfectly span two blocks, we can get those blocks directly + if (topBlockBits == 0) + { + mantissa = ((ulong)(value.GetBlock(middleBlockIndex)) << 32) + value.GetBlock(bottomBlockIndex); + } + else + { + // Otherwise, we need to read three blocks and combine them into a 64-bit mantissa + + int bottomBlockShift = (int)(topBlockBits); + int topBlockShift = 64 - bottomBlockShift; + int middleBlockShift = topBlockShift - 32; + + exponent += (int)(topBlockBits); + + uint bottomBlock = value.GetBlock(bottomBlockIndex); + uint bottomBits = bottomBlock >> bottomBlockShift; + + ulong middleBits = (ulong)(value.GetBlock(middleBlockIndex)) << middleBlockShift; + ulong topBits = (ulong)(value.GetBlock(topBlockIndex)) << topBlockShift; + + mantissa = topBits + middleBits + bottomBits; + + uint unusedBottomBlockBitsMask = (1u << (int)(topBlockBits)) - 1; + hasZeroTail &= (bottomBlock & unusedBottomBlockBitsMask) == 0; + } + + for (uint i = 0; i != bottomBlockIndex; i++) + { + hasZeroTail &= (value.GetBlock(i) == 0); + } + + return AssembleFloatingPointBits(in info, mantissa, exponent, hasZeroTail); + } + + // get 32-bit integer from at most 9 digits + private static uint DigitsToUInt32(byte* p, int count) + { + Debug.Assert((1 <= count) && (count <= 9)); + + byte* end = (p + count); + uint res = (uint)(p[0] - '0'); + + for (p++; p < end; p++) + { + res = (10 * res) + p[0] - '0'; + } + + return res; + } + + // get 64-bit integer from at most 19 digits + private static ulong DigitsToUInt64(byte* p, int count) + { + Debug.Assert((1 <= count) && (count <= 19)); + + byte* end = (p + count); + ulong res = (ulong)(p[0] - '0'); + + for (p++; p < end; p++) + { + res = (10 * res) + p[0] - '0'; + } + + return res; + } + + private static ulong NumberToFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info) + { + Debug.Assert(number.GetDigitsPointer()[0] != '0'); + + Debug.Assert(number.Scale <= FloatingPointMaxExponent); + Debug.Assert(number.Scale >= FloatingPointMinExponent); + + Debug.Assert(number.DigitsCount != 0); + + // The input is of the form 0.Mantissa x 10^Exponent, where 'Mantissa' are + // the decimal digits of the mantissa and 'Exponent' is the decimal exponent. + // We decompose the mantissa into two parts: an integer part and a fractional + // part. If the exponent is positive, then the integer part consists of the + // first 'exponent' digits, or all present digits if there are fewer digits. + // If the exponent is zero or negative, then the integer part is empty. In + // either case, the remaining digits form the fractional part of the mantissa. + + uint totalDigits = (uint)(number.DigitsCount); + uint positiveExponent = (uint)(Math.Max(0, number.Scale)); + + uint integerDigitsPresent = Math.Min(positiveExponent, totalDigits); + uint fractionalDigitsPresent = totalDigits - integerDigitsPresent; + + uint fastExponent = (uint)(Math.Abs(number.Scale - integerDigitsPresent - fractionalDigitsPresent)); + + // When the number of significant digits is less than or equal to 15 and the + // scale is less than or equal to 22, we can take some shortcuts and just rely + // on floating-point arithmetic to compute the correct result. This is + // because each floating-point precision values allows us to exactly represent + // different whole integers and certain powers of 10, depending on the underlying + // formats exact range. Additionally, IEEE operations dictate that the result is + // computed to the infinitely precise result and then rounded, which means that + // we can rely on it to produce the correct result when both inputs are exact. + + byte* src = number.GetDigitsPointer(); + + if ((info.DenormalMantissaBits == 23) && (totalDigits <= 7) && (fastExponent <= 10)) + { + // It is only valid to do this optimization for single-precision floating-point + // values since we can lose some of the mantissa bits and would return the + // wrong value when upcasting to double. + + float result = DigitsToUInt32(src, (int)(totalDigits)); + float scale = s_Pow10SingleTable[fastExponent]; + + if (fractionalDigitsPresent != 0) + { + result /= scale; + } + else + { + result *= scale; + } + + return (uint)(SingleToInt32Bits(result)); + } + + if ((totalDigits <= 15) && (fastExponent <= 22)) + { + double result = DigitsToUInt64(src, (int)(totalDigits)); + double scale = s_Pow10DoubleTable[fastExponent]; + + if (fractionalDigitsPresent != 0) + { + result /= scale; + } + else + { + result *= scale; + } + + if (info.DenormalMantissaBits == 52) + { + return (ulong)(BitConverter.DoubleToInt64Bits(result)); + } + else + { + Debug.Assert(info.DenormalMantissaBits == 23); + return (uint)(SingleToInt32Bits((float)(result))); + } + } + + return NumberToFloatingPointBitsSlow(ref number, in info, positiveExponent, integerDigitsPresent, fractionalDigitsPresent); + } + + private static ulong NumberToFloatingPointBitsSlow(ref NumberBuffer number, in FloatingPointInfo info, uint positiveExponent, uint integerDigitsPresent, uint fractionalDigitsPresent) + { + // To generate an N bit mantissa we require N + 1 bits of precision. The + // extra bit is used to correctly round the mantissa (if there are fewer bits + // than this available, then that's totally okay; in that case we use what we + // have and we don't need to round). + uint requiredBitsOfPrecision = (uint)(info.NormalMantissaBits + 1); + + uint totalDigits = (uint)(number.DigitsCount); + uint integerDigitsMissing = positiveExponent - integerDigitsPresent; + + const uint IntegerFirstIndex = 0; + uint integerLastIndex = integerDigitsPresent; + + uint fractionalFirstIndex = integerLastIndex; + uint fractionalLastIndex = totalDigits; + + // First, we accumulate the integer part of the mantissa into a big_integer: + AccumulateDecimalDigitsIntoBigInteger(ref number, IntegerFirstIndex, integerLastIndex, out BigInteger integerValue); + + if (integerDigitsMissing > 0) + { + if (integerDigitsMissing > info.OverflowDecimalExponent) + { + return info.InfinityBits; + } + + integerValue.MultiplyPow10(integerDigitsMissing); + } + + // At this point, the integer_value contains the value of the integer part + // of the mantissa. If either [1] this number has more than the required + // number of bits of precision or [2] the mantissa has no fractional part, + // then we can assemble the result immediately: + uint integerBitsOfPrecision = BigInteger.CountSignificantBits(ref integerValue); + + if ((integerBitsOfPrecision >= requiredBitsOfPrecision) || (fractionalDigitsPresent == 0)) + { + return ConvertBigIntegerToFloatingPointBits( + ref integerValue, + in info, + integerBitsOfPrecision, + fractionalDigitsPresent != 0 + ); + } + + // Otherwise, we did not get enough bits of precision from the integer part, + // and the mantissa has a fractional part. We parse the fractional part of + // the mantissa to obtain more bits of precision. To do this, we convert + // the fractional part into an actual fraction N/M, where the numerator N is + // computed from the digits of the fractional part, and the denominator M is + // computed as the power of 10 such that N/M is equal to the value of the + // fractional part of the mantissa. + + uint fractionalDenominatorExponent = fractionalDigitsPresent; + + if (number.Scale < 0) + { + fractionalDenominatorExponent += (uint)(-number.Scale); + } + + if ((integerBitsOfPrecision == 0) && (fractionalDenominatorExponent - (int)(totalDigits)) > info.OverflowDecimalExponent) + { + // If there were any digits in the integer part, it is impossible to + // underflow (because the exponent cannot possibly be small enough), + // so if we underflow here it is a true underflow and we return zero. + return info.ZeroBits; + } + + AccumulateDecimalDigitsIntoBigInteger(ref number, fractionalFirstIndex, fractionalLastIndex, out BigInteger fractionalNumerator); + + if (fractionalNumerator.IsZero()) + { + return ConvertBigIntegerToFloatingPointBits( + ref integerValue, + in info, + integerBitsOfPrecision, + fractionalDigitsPresent != 0 + ); + } + + BigInteger.Pow10(fractionalDenominatorExponent, out BigInteger fractionalDenominator); + + // Because we are using only the fractional part of the mantissa here, the + // numerator is guaranteed to be smaller than the denominator. We normalize + // the fraction such that the most significant bit of the numerator is in + // the same position as the most significant bit in the denominator. This + // ensures that when we later shift the numerator N bits to the left, we + // will produce N bits of precision. + uint fractionalNumeratorBits = BigInteger.CountSignificantBits(ref fractionalNumerator); + uint fractionalDenominatorBits = BigInteger.CountSignificantBits(ref fractionalDenominator); + + uint fractionalShift = 0; + + if (fractionalDenominatorBits > fractionalNumeratorBits) + { + fractionalShift = fractionalDenominatorBits - fractionalNumeratorBits; + } + + if (fractionalShift > 0) + { + fractionalNumerator.ShiftLeft(fractionalShift); + } + + uint requiredFractionalBitsOfPrecision = requiredBitsOfPrecision - integerBitsOfPrecision; + uint remainingBitsOfPrecisionRequired = requiredFractionalBitsOfPrecision; + + if (integerBitsOfPrecision > 0) + { + // If the fractional part of the mantissa provides no bits of precision + // and cannot affect rounding, we can just take whatever bits we got from + // the integer part of the mantissa. This is the case for numbers like + // 5.0000000000000000000001, where the significant digits of the fractional + // part start so far to the right that they do not affect the floating + // point representation. + // + // If the fractional shift is exactly equal to the number of bits of + // precision that we require, then no fractional bits will be part of the + // result, but the result may affect rounding. This is e.g. the case for + // large, odd integers with a fractional part greater than or equal to .5. + // Thus, we need to do the division to correctly round the result. + if (fractionalShift > remainingBitsOfPrecisionRequired) + { + return ConvertBigIntegerToFloatingPointBits( + ref integerValue, + in info, + integerBitsOfPrecision, + fractionalDigitsPresent != 0 + ); + } + + remainingBitsOfPrecisionRequired -= fractionalShift; + } + + // If there was no integer part of the mantissa, we will need to compute the + // exponent from the fractional part. The fractional exponent is the power + // of two by which we must multiply the fractional part to move it into the + // range [1.0, 2.0). This will either be the same as the shift we computed + // earlier, or one greater than that shift: + uint fractionalExponent = fractionalShift; + + if (BigInteger.Compare(ref fractionalNumerator, ref fractionalDenominator) < 0) + { + fractionalExponent++; + } + + fractionalNumerator.ShiftLeft(remainingBitsOfPrecisionRequired); + + BigInteger.DivRem(ref fractionalNumerator, ref fractionalDenominator, out BigInteger bigFractionalMantissa, out BigInteger fractionalRemainder); + ulong fractionalMantissa = bigFractionalMantissa.ToUInt64(); + bool hasZeroTail = !number.HasNonZeroTail && fractionalRemainder.IsZero(); + + // We may have produced more bits of precision than were required. Check, + // and remove any "extra" bits: + uint fractionalMantissaBits = BigInteger.CountSignificantBits(fractionalMantissa); + + if (fractionalMantissaBits > requiredFractionalBitsOfPrecision) + { + int shift = (int)(fractionalMantissaBits - requiredFractionalBitsOfPrecision); + hasZeroTail = hasZeroTail && (fractionalMantissa & ((1UL << shift) - 1)) == 0; + fractionalMantissa >>= shift; + } + + // Compose the mantissa from the integer and fractional parts: + ulong integerMantissa = integerValue.ToUInt64(); + ulong completeMantissa = (integerMantissa << (int)(requiredFractionalBitsOfPrecision)) + fractionalMantissa; + + // Compute the final exponent: + // * If the mantissa had an integer part, then the exponent is one less than + // the number of bits we obtained from the integer part. (It's one less + // because we are converting to the form 1.11111, with one 1 to the left + // of the decimal point.) + // * If the mantissa had no integer part, then the exponent is the fractional + // exponent that we computed. + // Then, in both cases, we subtract an additional one from the exponent, to + // account for the fact that we've generated an extra bit of precision, for + // use in rounding. + int finalExponent = (integerBitsOfPrecision > 0) ? (int)(integerBitsOfPrecision) - 2 : -(int)(fractionalExponent) - 1; + + return AssembleFloatingPointBits(in info, completeMantissa, finalExponent, hasZeroTail); + } + + private static ulong RightShiftWithRounding(ulong value, int shift, bool hasZeroTail) + { + // If we'd need to shift further than it is possible to shift, the answer + // is always zero: + if (shift >= 64) + { + return 0; + } + + ulong extraBitsMask = (1UL << (shift - 1)) - 1; + ulong roundBitMask = (1UL << (shift - 1)); + ulong lsbBitMask = 1UL << shift; + + bool lsbBit = (value & lsbBitMask) != 0; + bool roundBit = (value & roundBitMask) != 0; + bool hasTailBits = !hasZeroTail || (value & extraBitsMask) != 0; + + return (value >> shift) + (ShouldRoundUp(lsbBit, roundBit, hasTailBits) ? 1UL : 0); + } + + private static bool ShouldRoundUp(bool lsbBit, bool roundBit, bool hasTailBits) + { + // If there are insignificant set bits, we need to round to the + // nearest; there are two cases: + // we round up if either [1] the value is slightly greater than the midpoint + // between two exactly representable values or [2] the value is exactly the + // midpoint between two exactly representable values and the greater of the + // two is even (this is "round-to-even"). + return roundBit && (hasTailBits || lsbBit); + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/Number.Parsing.cs b/src/ZString/Number/Number.Parsing.cs new file mode 100644 index 00000000..42924699 --- /dev/null +++ b/src/ZString/Number/Number.Parsing.cs @@ -0,0 +1,2028 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System +{ + // The Parse methods provided by the numeric classes convert a + // string to a numeric value. The optional style parameter specifies the + // permitted style of the numeric string. It must be a combination of bit flags + // from the NumberStyles enumeration. The optional info parameter + // specifies the NumberFormatInfo instance to use when parsing the + // string. If the info parameter is null or omitted, the numeric + // formatting information is obtained from the current culture. + // + // Numeric strings produced by the Format methods using the Currency, + // Decimal, Engineering, Fixed point, General, or Number standard formats + // (the C, D, E, F, G, and N format specifiers) are guaranteed to be parseable + // by the Parse methods if the NumberStyles.Any style is + // specified. Note, however, that the Parse methods do not accept + // NaNs or Infinities. + + internal static partial class Number + { + private const int Int32Precision = 10; + private const int UInt32Precision = Int32Precision; + private const int Int64Precision = 19; + private const int UInt64Precision = 20; + + private const int DoubleMaxExponent = 309; + private const int DoubleMinExponent = -324; + + private const int FloatingPointMaxExponent = DoubleMaxExponent; + private const int FloatingPointMinExponent = DoubleMinExponent; + + private const int SingleMaxExponent = 39; + private const int SingleMinExponent = -45; + + /// Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit. + internal static ReadOnlySpan CharToHexLookup => new byte[] + { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 15 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 31 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 47 + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 63 + 0xFF, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 79 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 95 + 0xFF, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf // 102 + }; + + private static unsafe bool TryNumberToInt32(ref NumberBuffer number, ref int value) + { + number.CheckConsistency(); + + int i = number.Scale; + if (i > Int32Precision || i < number.DigitsCount) + { + return false; + } + byte* p = number.GetDigitsPointer(); + Debug.Assert(p != null); + int n = 0; + while (--i >= 0) + { + if ((uint)n > (0x7FFFFFFF / 10)) + { + return false; + } + n *= 10; + if (*p != '\0') + { + n += (*p++ - '0'); + } + } + if (number.IsNegative) + { + n = -n; + if (n > 0) + { + return false; + } + } + else + { + if (n < 0) + { + return false; + } + } + value = n; + return true; + } + + private static unsafe bool TryNumberToInt64(ref NumberBuffer number, ref long value) + { + number.CheckConsistency(); + + int i = number.Scale; + if (i > Int64Precision || i < number.DigitsCount) + { + return false; + } + byte* p = number.GetDigitsPointer(); + Debug.Assert(p != null); + long n = 0; + while (--i >= 0) + { + if ((ulong)n > (0x7FFFFFFFFFFFFFFF / 10)) + { + return false; + } + n *= 10; + if (*p != '\0') + { + n += (*p++ - '0'); + } + } + if (number.IsNegative) + { + n = -n; + if (n > 0) + { + return false; + } + } + else + { + if (n < 0) + { + return false; + } + } + value = n; + return true; + } + + private static unsafe bool TryNumberToUInt32(ref NumberBuffer number, ref uint value) + { + number.CheckConsistency(); + + int i = number.Scale; + if (i > UInt32Precision || i < number.DigitsCount || number.IsNegative) + { + return false; + } + byte* p = number.GetDigitsPointer(); + Debug.Assert(p != null); + uint n = 0; + while (--i >= 0) + { + if (n > (0xFFFFFFFF / 10)) + { + return false; + } + n *= 10; + if (*p != '\0') + { + uint newN = n + (uint)(*p++ - '0'); + // Detect an overflow here... + if (newN < n) + { + return false; + } + n = newN; + } + } + value = n; + return true; + } + + private static unsafe bool TryNumberToUInt64(ref NumberBuffer number, ref ulong value) + { + number.CheckConsistency(); + + int i = number.Scale; + if (i > UInt64Precision || i < number.DigitsCount || number.IsNegative) + { + return false; + } + byte* p = number.GetDigitsPointer(); + Debug.Assert(p != null); + ulong n = 0; + while (--i >= 0) + { + if (n > (0xFFFFFFFFFFFFFFFF / 10)) + { + return false; + } + n *= 10; + if (*p != '\0') + { + ulong newN = n + (ulong)(*p++ - '0'); + // Detect an overflow here... + if (newN < n) + { + return false; + } + n = newN; + } + } + value = n; + return true; + } + + internal static int ParseInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseInt32(value, styles, info, out int result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.Int32); + } + + return result; + } + + internal static long ParseInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseInt64(value, styles, info, out long result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.Int64); + } + + return result; + } + + internal static uint ParseUInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseUInt32(value, styles, info, out uint result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.UInt32); + } + + return result; + } + + internal static ulong ParseUInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseUInt64(value, styles, info, out ulong result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.UInt64); + } + + return result; + } + + private static unsafe bool TryParseNumber(ref char* str, char* strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info) + { + Debug.Assert(str != null); + Debug.Assert(strEnd != null); + Debug.Assert(str <= strEnd); + Debug.Assert((styles & NumberStyles.AllowHexSpecifier) == 0); + + const int StateSign = 0x0001; + const int StateParens = 0x0002; + const int StateDigits = 0x0004; + const int StateNonZero = 0x0008; + const int StateDecimal = 0x0010; + const int StateCurrency = 0x0020; + + Debug.Assert(number.DigitsCount == 0); + Debug.Assert(number.Scale == 0); + Debug.Assert(!number.IsNegative); + Debug.Assert(!number.HasNonZeroTail); + + number.CheckConsistency(); + + string decSep; // decimal separator from NumberFormatInfo. + string groupSep; // group separator from NumberFormatInfo. + string currSymbol = null; // currency symbol from NumberFormatInfo. + + bool parsingCurrency = false; + if ((styles & NumberStyles.AllowCurrencySymbol) != 0) + { + currSymbol = info.CurrencySymbol; + + // The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast. + // The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part). + decSep = info.CurrencyDecimalSeparator; + groupSep = info.CurrencyGroupSeparator; + parsingCurrency = true; + } + else + { + decSep = info.NumberDecimalSeparator; + groupSep = info.NumberGroupSeparator; + } + + int state = 0; + char* p = str; + char ch = p < strEnd ? *p : '\0'; + char* next; + + while (true) + { + // Eat whitespace unless we've found a sign which isn't followed by a currency symbol. + // "-Kr 1231.47" is legal but "- 1231.47" is not. + if (!IsWhite(ch) || (styles & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && info.NumberNegativePattern != 2))) + { + if ((((styles & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || ((next = MatchChars(p, strEnd, info.NegativeSign)) != null && (number.IsNegative = true)))) + { + state |= StateSign; + p = next - 1; + } + else if (ch == '(' && ((styles & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0)) + { + state |= StateSign | StateParens; + number.IsNegative = true; + } + else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) + { + state |= StateCurrency; + currSymbol = null; + // We already found the currency symbol. There should not be more currency symbols. Set + // currSymbol to NULL so that we won't search it again in the later code path. + p = next - 1; + } + else + { + break; + } + } + ch = ++p < strEnd ? *p : '\0'; + } + + int digCount = 0; + int digEnd = 0; + int maxDigCount = number.Digits.Length - 1; + + while (true) + { + if (IsDigit(ch)) + { + state |= StateDigits; + + if (ch != '0' || (state & StateNonZero) != 0) + { + if (digCount < maxDigCount) + { + number.Digits[digCount++] = (byte)(ch); + if ((ch != '0') || (number.Kind != NumberBufferKind.Integer)) + { + digEnd = digCount; + } + } + else if (ch != '0') + { + // For decimal and binary floating-point numbers, we only + // need to store digits up to maxDigCount. However, we still + // need to keep track of whether any additional digits past + // maxDigCount were non-zero, as that can impact rounding + // for an input that falls evenly between two representable + // results. + + number.HasNonZeroTail = true; + } + + if ((state & StateDecimal) == 0) + { + number.Scale++; + } + state |= StateNonZero; + } + else if ((state & StateDecimal) != 0) + { + number.Scale--; + } + } + else if (((styles & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, decSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberDecimalSeparator)) != null)) + { + state |= StateDecimal; + p = next - 1; + } + else if (((styles & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, groupSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberGroupSeparator)) != null)) + { + p = next - 1; + } + else + { + break; + } + ch = ++p < strEnd ? *p : '\0'; + } + + bool negExp = false; + number.DigitsCount = digEnd; + number.Digits[digEnd] = (byte)('\0'); + if ((state & StateDigits) != 0) + { + if ((ch == 'E' || ch == 'e') && ((styles & NumberStyles.AllowExponent) != 0)) + { + char* temp = p; + ch = ++p < strEnd ? *p : '\0'; + if ((next = MatchChars(p, strEnd, info.PositiveSign)) != null) + { + ch = (p = next) < strEnd ? *p : '\0'; + } + else if ((next = MatchChars(p, strEnd, info.NegativeSign)) != null) + { + ch = (p = next) < strEnd ? *p : '\0'; + negExp = true; + } + if (IsDigit(ch)) + { + int exp = 0; + do + { + exp = exp * 10 + (ch - '0'); + ch = ++p < strEnd ? *p : '\0'; + if (exp > 1000) + { + exp = 9999; + while (IsDigit(ch)) + { + ch = ++p < strEnd ? *p : '\0'; + } + } + } while (IsDigit(ch)); + if (negExp) + { + exp = -exp; + } + number.Scale += exp; + } + else + { + p = temp; + ch = p < strEnd ? *p : '\0'; + } + } + while (true) + { + if (!IsWhite(ch) || (styles & NumberStyles.AllowTrailingWhite) == 0) + { + if ((styles & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || (((next = MatchChars(p, strEnd, info.NegativeSign)) != null) && (number.IsNegative = true)))) + { + state |= StateSign; + p = next - 1; + } + else if (ch == ')' && ((state & StateParens) != 0)) + { + state &= ~StateParens; + } + else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) + { + currSymbol = null; + p = next - 1; + } + else + { + break; + } + } + ch = ++p < strEnd ? *p : '\0'; + } + if ((state & StateParens) == 0) + { + if ((state & StateNonZero) == 0) + { + if (number.Kind != NumberBufferKind.Decimal) + { + number.Scale = 0; + } + if ((number.Kind == NumberBufferKind.Integer) && (state & StateDecimal) == 0) + { + number.IsNegative = false; + } + } + str = p; + return true; + } + } + str = p; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ParsingStatus TryParseInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) + { + if ((styles & ~NumberStyles.Integer) == 0) + { + // Optimized path for the common case of anything that's allowed for integer style. + return TryParseInt32IntegerStyle(value, styles, info, out result); + } + + if ((styles & NumberStyles.AllowHexSpecifier) != 0) + { + result = 0; + return TryParseUInt32HexNumberStyle(value, styles, out Unsafe.As(ref result)); + } + + return TryParseInt32Number(value, styles, info, out result); + } + + private static unsafe ParsingStatus TryParseInt32Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) + { + result = 0; + byte* pDigits = stackalloc byte[Int32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToInt32(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + /// Parses int limited to styles that make up NumberStyles.Integer. + internal static ParsingStatus TryParseInt32IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) + { + Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + // Parse leading sign. + int sign = 1; + if ((styles & NumberStyles.AllowLeadingSign) != 0) + { + if (info.HasInvariantNumberSigns()) + { + if (num == '-') + { + sign = -1; + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (num == '+') + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + else + { + value = value.Slice(index); + index = 0; + string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; + if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) + { + index += positiveSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) + { + sign = -1; + index += negativeSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + } + + bool overflow = false; + int answer = 0; + + if (IsDigit(num)) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if (!IsDigit(num)) + goto HasTrailingChars; + } + + // Parse most digits, up to the potential for overflow, which can't happen until after 9 digits. + answer = num - '0'; // first digit + index++; + for (int i = 0; i < 8; i++) // next 8 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + answer = 10 * answer + num - '0'; + } + + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + // Potential overflow now processing the 10th digit. + overflow = answer > int.MaxValue / 10; + answer = answer * 10 + num - '0'; + overflow |= (uint)answer > int.MaxValue + (((uint)sign) >> 31); + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. + num = value[index]; + while (IsDigit(num)) + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = answer * sign; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + /// Parses long inputs limited to styles that make up NumberStyles.Integer. + internal static ParsingStatus TryParseInt64IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) + { + Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + // Parse leading sign. + int sign = 1; + if ((styles & NumberStyles.AllowLeadingSign) != 0) + { + if (info.HasInvariantNumberSigns()) + { + if (num == '-') + { + sign = -1; + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (num == '+') + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + else + { + value = value.Slice(index); + index = 0; + string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; + if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) + { + index += positiveSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) + { + sign = -1; + index += negativeSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + } + + bool overflow = false; + long answer = 0; + + if (IsDigit(num)) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if (!IsDigit(num)) + goto HasTrailingChars; + } + + // Parse most digits, up to the potential for overflow, which can't happen until after 18 digits. + answer = num - '0'; // first digit + index++; + for (int i = 0; i < 17; i++) // next 17 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + answer = 10 * answer + num - '0'; + } + + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + // Potential overflow now processing the 19th digit. + overflow = answer > long.MaxValue / 10; + answer = answer * 10 + num - '0'; + overflow |= (ulong)answer > (ulong)long.MaxValue + (((uint)sign) >> 31); + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. + num = value[index]; + while (IsDigit(num)) + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = answer * sign; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ParsingStatus TryParseInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) + { + if ((styles & ~NumberStyles.Integer) == 0) + { + // Optimized path for the common case of anything that's allowed for integer style. + return TryParseInt64IntegerStyle(value, styles, info, out result); + } + + if ((styles & NumberStyles.AllowHexSpecifier) != 0) + { + result = 0; + return TryParseUInt64HexNumberStyle(value, styles, out Unsafe.As(ref result)); + } + + return TryParseInt64Number(value, styles, info, out result); + } + + private static unsafe ParsingStatus TryParseInt64Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) + { + result = 0; + byte* pDigits = stackalloc byte[Int64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToInt64(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ParsingStatus TryParseUInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) + { + if ((styles & ~NumberStyles.Integer) == 0) + { + // Optimized path for the common case of anything that's allowed for integer style. + return TryParseUInt32IntegerStyle(value, styles, info, out result); + } + + if ((styles & NumberStyles.AllowHexSpecifier) != 0) + { + return TryParseUInt32HexNumberStyle(value, styles, out result); + } + + return TryParseUInt32Number(value, styles, info, out result); + } + + private static unsafe ParsingStatus TryParseUInt32Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) + { + result = 0; + byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToUInt32(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + /// Parses uint limited to styles that make up NumberStyles.Integer. + internal static ParsingStatus TryParseUInt32IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) + { + Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + // Parse leading sign. + bool overflow = false; + if ((styles & NumberStyles.AllowLeadingSign) != 0) + { + if (info.HasInvariantNumberSigns()) + { + if (num == '+') + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (num == '-') + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + else + { + value = value.Slice(index); + index = 0; + string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; + if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) + { + index += positiveSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) + { + overflow = true; + index += negativeSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + } + + int answer = 0; + + if (IsDigit(num)) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if (!IsDigit(num)) + goto HasTrailingCharsZero; + } + + // Parse most digits, up to the potential for overflow, which can't happen until after 9 digits. + answer = num - '0'; // first digit + index++; + for (int i = 0; i < 8; i++) // next 8 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + answer = 10 * answer + num - '0'; + } + + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + // Potential overflow now processing the 10th digit. + overflow |= (uint)answer > uint.MaxValue / 10 || ((uint)answer == uint.MaxValue / 10 && num > '5'); + answer = answer * 10 + num - '0'; + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. + num = value[index]; + while (IsDigit(num)) + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = (uint)answer; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingCharsZero: + overflow = false; + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + /// Parses uint limited to styles that make up NumberStyles.HexNumber. + private static ParsingStatus TryParseUInt32HexNumberStyle(ReadOnlySpan value, NumberStyles styles, out uint result) + { + Debug.Assert((styles & ~NumberStyles.HexNumber) == 0, "Only handles subsets of HexNumber format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + bool overflow = false; + uint answer = 0; + ReadOnlySpan charToHexLookup = CharToHexLookup; + + if ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) + goto HasTrailingChars; + } + + // Parse up through 8 digits, as no overflow is possible + answer = charToHexLookup[num]; // first digit + index++; + for (int i = 0; i < 7; i++) // next 7 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + + uint numValue; + if ((uint)num >= (uint)charToHexLookup.Length || (numValue = charToHexLookup[num]) == 0xFF) + goto HasTrailingChars; + index++; + answer = 16 * answer + numValue; + } + + // If there's another digit, it's an overflow. + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) + goto HasTrailingChars; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. Read through any remaining digits. + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } while ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF); + overflow = true; + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = answer; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ParsingStatus TryParseUInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) + { + if ((styles & ~NumberStyles.Integer) == 0) + { + // Optimized path for the common case of anything that's allowed for integer style. + return TryParseUInt64IntegerStyle(value, styles, info, out result); + } + + if ((styles & NumberStyles.AllowHexSpecifier) != 0) + { + return TryParseUInt64HexNumberStyle(value, styles, out result); + } + + return TryParseUInt64Number(value, styles, info, out result); + } + + private static unsafe ParsingStatus TryParseUInt64Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) + { + result = 0; + byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToUInt64(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + /// Parses ulong limited to styles that make up NumberStyles.Integer. + internal static ParsingStatus TryParseUInt64IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) + { + Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + // Parse leading sign. + bool overflow = false; + if ((styles & NumberStyles.AllowLeadingSign) != 0) + { + if (info.HasInvariantNumberSigns()) + { + if (num == '+') + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (num == '-') + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + else + { + value = value.Slice(index); + index = 0; + string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; + if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) + { + index += positiveSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) + { + overflow = true; + index += negativeSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + } + + long answer = 0; + + if (IsDigit(num)) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if (!IsDigit(num)) + goto HasTrailingCharsZero; + } + + // Parse most digits, up to the potential for overflow, which can't happen until after 19 digits. + answer = num - '0'; // first digit + index++; + for (int i = 0; i < 18; i++) // next 18 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + answer = 10 * answer + num - '0'; + } + + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + // Potential overflow now processing the 20th digit. + overflow |= (ulong)answer > ulong.MaxValue / 10 || ((ulong)answer == ulong.MaxValue / 10 && num > '5'); + answer = answer * 10 + num - '0'; + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. + num = value[index]; + while (IsDigit(num)) + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = (ulong)answer; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingCharsZero: + overflow = false; + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + /// Parses ulong limited to styles that make up NumberStyles.HexNumber. + private static ParsingStatus TryParseUInt64HexNumberStyle(ReadOnlySpan value, NumberStyles styles, out ulong result) + { + Debug.Assert((styles & ~NumberStyles.HexNumber) == 0, "Only handles subsets of HexNumber format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + bool overflow = false; + ulong answer = 0; + ReadOnlySpan charToHexLookup = CharToHexLookup; + + if ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) + goto HasTrailingChars; + } + + // Parse up through 16 digits, as no overflow is possible + answer = charToHexLookup[num]; // first digit + index++; + for (int i = 0; i < 15; i++) // next 15 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + + uint numValue; + if ((uint)num >= (uint)charToHexLookup.Length || (numValue = charToHexLookup[num]) == 0xFF) + goto HasTrailingChars; + index++; + answer = 16 * answer + numValue; + } + + // If there's another digit, it's an overflow. + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) + goto HasTrailingChars; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. Read through any remaining digits. + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } while ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF); + overflow = true; + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = answer; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + internal static decimal ParseDecimal(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseDecimal(value, styles, info, out decimal result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.Decimal); + } + + return result; + } + + internal static unsafe bool TryNumberToDecimal(ref NumberBuffer number, ref decimal value) + { + number.CheckConsistency(); + + byte* p = number.GetDigitsPointer(); + int e = number.Scale; + bool sign = number.IsNegative; + uint c = *p; + if (c == 0) + { + // To avoid risking an app-compat issue with pre 4.5 (where some app was illegally using Reflection to examine the internal scale bits), we'll only force + // the scale to 0 if the scale was previously positive (previously, such cases were unparsable to a bug.) + value = new decimal(0, 0, 0, sign, (byte)MathEx.Clamp(-e, 0, 28)); + return true; + } + + if (e > DecimalPrecision) + return false; + + ulong low64 = 0; + while (e > -28) + { + e--; + low64 *= 10; + low64 += c - '0'; + c = *++p; + if (low64 >= ulong.MaxValue / 10) + break; + if (c == 0) + { + while (e > 0) + { + e--; + low64 *= 10; + if (low64 >= ulong.MaxValue / 10) + break; + } + break; + } + } + + uint high = 0; + while ((e > 0 || (c != 0 && e > -28)) && + (high < uint.MaxValue / 10 || (high == uint.MaxValue / 10 && (low64 < 0x99999999_99999999 || (low64 == 0x99999999_99999999 && c <= '5'))))) + { + // multiply by 10 + ulong tmpLow = (uint)low64 * 10UL; + ulong tmp64 = (uint)(low64 >> 32) * 10UL + (tmpLow >> 32); + low64 = (uint)tmpLow + (tmp64 << 32); + high = (uint)(tmp64 >> 32) + high * 10; + + if (c != 0) + { + c -= '0'; + low64 += c; + if (low64 < c) + high++; + c = *++p; + } + e--; + } + + if (c >= '5') + { + if ((c == '5') && ((low64 & 1) == 0)) + { + c = *++p; + + bool hasZeroTail = !number.HasNonZeroTail; + + // We might still have some additional digits, in which case they need + // to be considered as part of hasZeroTail. Some examples of this are: + // * 3.0500000000000000000001e-27 + // * 3.05000000000000000000001e-27 + // In these cases, we will have processed 3 and 0, and ended on 5. The + // buffer, however, will still contain a number of trailing zeros and + // a trailing non-zero number. + + while ((c != 0) && hasZeroTail) + { + hasZeroTail &= (c == '0'); + c = *++p; + } + + // We should either be at the end of the stream or have a non-zero tail + Debug.Assert((c == 0) || !hasZeroTail); + + if (hasZeroTail) + { + // When the next digit is 5, the number is even, and all following + // digits are zero we don't need to round. + goto NoRounding; + } + } + + if (++low64 == 0 && ++high == 0) + { + low64 = 0x99999999_9999999A; + high = uint.MaxValue / 10; + e++; + } + } + NoRounding: + + if (e > 0) + return false; + + if (e <= -DecimalPrecision) + { + // Parsing a large scale zero can give you more precision than fits in the decimal. + // This should only happen for actual zeros or very small numbers that round to zero. + value = new decimal(0, 0, 0, sign, DecimalPrecision - 1); + } + else + { + value = new decimal((int)low64, (int)(low64 >> 32), (int)high, sign, (byte)-e); + } + return true; + } + + internal static double ParseDouble(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + if (!TryParseDouble(value, styles, info, out double result)) + { + ThrowOverflowOrFormatException(ParsingStatus.Failed); + } + + return result; + } + + internal static float ParseSingle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + if (!TryParseSingle(value, styles, info, out float result)) + { + ThrowOverflowOrFormatException(ParsingStatus.Failed); + } + + return result; + } + + internal static unsafe ParsingStatus TryParseDecimal(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out decimal result) + { + byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); + + result = 0; + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToDecimal(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + internal static unsafe bool TryParseDouble(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out double result) + { + byte* pDigits = stackalloc byte[DoubleNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, DoubleNumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + ReadOnlySpan valueTrim = value.Trim(); + + // This code would be simpler if we only had the concept of `InfinitySymbol`, but + // we don't so we'll check the existing cases first and then handle `PositiveSign` + + // `PositiveInfinitySymbol` and `PositiveSign/NegativeSign` + `NaNSymbol` last. + + if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) + { + result = double.PositiveInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol.AsSpan())) + { + result = double.NegativeInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = double.NaN; + } + else if (valueTrim.StartsWith(info.PositiveSign.AsSpan(), StringComparison.OrdinalIgnoreCase)) + { + valueTrim = valueTrim.Slice(info.PositiveSign.Length); + + if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) + { + result = double.PositiveInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = double.NaN; + } + else + { + result = 0; + return false; + } + } + else if (valueTrim.StartsWith(info.NegativeSign.AsSpan(), StringComparison.OrdinalIgnoreCase) && + valueTrim.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = double.NaN; + } + else + { + result = 0; + return false; // We really failed + } + } + else + { + result = NumberToDouble(ref number); + } + + return true; + } + + internal static unsafe bool TryParseSingle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out float result) + { + byte* pDigits = stackalloc byte[SingleNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, SingleNumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + ReadOnlySpan valueTrim = value.Trim(); + + // This code would be simpler if we only had the concept of `InfinitySymbol`, but + // we don't so we'll check the existing cases first and then handle `PositiveSign` + + // `PositiveInfinitySymbol` and `PositiveSign/NegativeSign` + `NaNSymbol` last. + // + // Additionally, since some cultures ("wo") actually define `PositiveInfinitySymbol` + // to include `PositiveSign`, we need to check whether `PositiveInfinitySymbol` fits + // that case so that we don't start parsing things like `++infini`. + + if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) + { + result = float.PositiveInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol.AsSpan())) + { + result = float.NegativeInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = float.NaN; + } + else if (valueTrim.StartsWith(info.PositiveSign.AsSpan(), StringComparison.OrdinalIgnoreCase)) + { + valueTrim = valueTrim.Slice(info.PositiveSign.Length); + + if (!info.PositiveInfinitySymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) && valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) + { + result = float.PositiveInfinity; + } + else if (!info.NaNSymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) && valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = float.NaN; + } + else + { + result = 0; + return false; + } + } + else if (valueTrim.StartsWith(info.NegativeSign.AsSpan(), StringComparison.OrdinalIgnoreCase) && + !info.NaNSymbol.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) && + valueTrim.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = float.NaN; + } + else + { + result = 0; + return false; // We really failed + } + } + else + { + result = NumberToSingle(ref number); + } + + return true; + } + + internal static unsafe bool TryStringToNumber(ReadOnlySpan value, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info) + { + Debug.Assert(info != null); + fixed (char* stringPointer = &MemoryMarshal.GetReference(value)) + { + char* p = stringPointer; + if (!TryParseNumber(ref p, p + value.Length, styles, ref number, info) + || ((int)(p - stringPointer) < value.Length && !TrailingZeros(value, (int)(p - stringPointer)))) + { + number.CheckConsistency(); + return false; + } + } + + number.CheckConsistency(); + return true; + } + + private static bool TrailingZeros(ReadOnlySpan value, int index) + { + // For compatibility, we need to allow trailing zeros at the end of a number string + for (int i = index; (uint)i < (uint)value.Length; i++) + { + if (value[i] != '\0') + { + return false; + } + } + + return true; + } + + private static bool IsSpaceReplacingChar(char c) => c == '\u00a0' || c == '\u202f'; + + private static unsafe char* MatchChars(char* p, char* pEnd, string value) + { + Debug.Assert(p != null && pEnd != null && p <= pEnd && value != null); + fixed (char* stringPointer = value) + { + char* str = stringPointer; + if (*str != '\0') + { + // We only hurt the failure case + // This fix is for French or Kazakh cultures. Since a user cannot type 0xA0 or 0x202F as a + // space character we use 0x20 space character instead to mean the same. + while (true) + { + char cp = p < pEnd ? *p : '\0'; + if (cp != *str && !(IsSpaceReplacingChar(*str) && cp == '\u0020')) + { + break; + } + p++; + str++; + if (*str == '\0') + return p; + } + } + } + + return null; + } + + // Ternary op is a workaround for https://github.com/dotnet/coreclr/issues/914 + private static bool IsWhite(int ch) => ch == 0x20 || (uint)(ch - 0x09) <= (0x0D - 0x09) ? true : false; + + private static bool IsDigit(int ch) => ((uint)ch - '0') <= 9; + + internal enum ParsingStatus + { + OK, + Failed, + Overflow + } + + internal static void ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type = 0) => throw GetException(status, type); + + internal static void ThrowOverflowException(TypeCode type) => throw GetException(ParsingStatus.Overflow, type); + + private static Exception GetException(ParsingStatus status, TypeCode type) + { + if (status == ParsingStatus.Failed) + return new FormatException(); + + string s; + switch (type) + { + case TypeCode.SByte: + s = "SR.Overflow_SByte"; + break; + case TypeCode.Byte: + s = "SR.Overflow_Byte"; + break; + case TypeCode.Int16: + s = "SR.Overflow_Int16"; + break; + case TypeCode.UInt16: + s = "SR.Overflow_UInt16"; + break; + case TypeCode.Int32: + s = "SR.Overflow_Int32"; + break; + case TypeCode.UInt32: + s = "SR.Overflow_UInt32"; + break; + case TypeCode.Int64: + s = "SR.Overflow_Int64"; + break; + case TypeCode.UInt64: + s = "SR.Overflow_UInt64"; + break; + default: + Debug.Assert(type == TypeCode.Decimal); + s = "SR.Overflow_Decimal"; + break; + } + return new OverflowException(s); + } + + internal static double NumberToDouble(ref NumberBuffer number) + { + number.CheckConsistency(); + double result; + + if ((number.DigitsCount == 0) || (number.Scale < DoubleMinExponent)) + { + result = 0; + } + else if (number.Scale > DoubleMaxExponent) + { + result = double.PositiveInfinity; + } + else + { + ulong bits = NumberToFloatingPointBits(ref number, in FloatingPointInfo.Double); + result = BitConverter.Int64BitsToDouble((long)(bits)); + } + + return number.IsNegative ? -result : result; + } + + internal static float NumberToSingle(ref NumberBuffer number) + { + number.CheckConsistency(); + float result; + + if ((number.DigitsCount == 0) || (number.Scale < SingleMinExponent)) + { + result = 0; + } + else if (number.Scale > SingleMaxExponent) + { + result = float.PositiveInfinity; + } + else + { + uint bits = (uint)(NumberToFloatingPointBits(ref number, in FloatingPointInfo.Single)); + result = Int32BitsToSingle((int)(bits)); + } + + return number.IsNegative ? -result : result; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe float Int32BitsToSingle(int value) + { + return *((float*)&value); + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/NumberFormatInfoEx.cs b/src/ZString/Number/NumberFormatInfoEx.cs new file mode 100644 index 00000000..785c6764 --- /dev/null +++ b/src/ZString/Number/NumberFormatInfoEx.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace System +{ + internal static class NumberFormatInfoEx + { + internal static bool HasInvariantNumberSigns(this NumberFormatInfo info) + { + return info.PositiveSign == "+" && info.NegativeSign == "-"; + } + } +} diff --git a/src/ZString/Number/ValueStringBuilder.cs b/src/ZString/Number/ValueStringBuilder.cs new file mode 100644 index 00000000..38afec71 --- /dev/null +++ b/src/ZString/Number/ValueStringBuilder.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Text +{ + internal ref partial struct ValueStringBuilder + { + private char[] _arrayToReturnToPool; + private Span _chars; + private int _pos; + + public ValueStringBuilder(Span initialBuffer) + { + _arrayToReturnToPool = null; + _chars = initialBuffer; + _pos = 0; + } + + public ValueStringBuilder(int initialCapacity) + { + _arrayToReturnToPool = ArrayPool.Shared.Rent(initialCapacity); + _chars = _arrayToReturnToPool; + _pos = 0; + } + + public int Length + { + get => _pos; + set + { + Debug.Assert(value >= 0); + Debug.Assert(value <= _chars.Length); + _pos = value; + } + } + + public int Capacity => _chars.Length; + + public void EnsureCapacity(int capacity) + { + if (capacity > _chars.Length) + Grow(capacity - _pos); + } + + /// + /// Get a pinnable reference to the builder. + /// Does not ensure there is a null char after + /// This overload is pattern matched in the C# 7.3+ compiler so you can omit + /// the explicit method call, and write eg "fixed (char* c = builder)" + /// + public ref char GetPinnableReference() + { + return ref MemoryMarshal.GetReference(_chars); + } + + /// + /// Get a pinnable reference to the builder. + /// + /// Ensures that the builder has a null char after + public ref char GetPinnableReference(bool terminate) + { + if (terminate) + { + EnsureCapacity(Length + 1); + _chars[Length] = '\0'; + } + return ref MemoryMarshal.GetReference(_chars); + } + + public ref char this[int index] + { + get + { + Debug.Assert(index < _pos); + return ref _chars[index]; + } + } + + public override string ToString() + { + string s = _chars.Slice(0, _pos).ToString(); + Dispose(); + return s; + } + + /// Returns the underlying storage of the builder. + public Span RawChars => _chars; + + /// + /// Returns a span around the contents of the builder. + /// + /// Ensures that the builder has a null char after + public ReadOnlySpan AsSpan(bool terminate) + { + if (terminate) + { + EnsureCapacity(Length + 1); + _chars[Length] = '\0'; + } + return _chars.Slice(0, _pos); + } + + public ReadOnlySpan AsSpan() => _chars.Slice(0, _pos); + public ReadOnlySpan AsSpan(int start) => _chars.Slice(start, _pos - start); + public ReadOnlySpan AsSpan(int start, int length) => _chars.Slice(start, length); + + public bool TryCopyTo(Span destination, out int charsWritten) + { + if (_chars.Slice(0, _pos).TryCopyTo(destination)) + { + charsWritten = _pos; + Dispose(); + return true; + } + else + { + charsWritten = 0; + Dispose(); + return false; + } + } + + public void Insert(int index, char value, int count) + { + if (_pos > _chars.Length - count) + { + Grow(count); + } + + int remaining = _pos - index; + _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); + _chars.Slice(index, count).Fill(value); + _pos += count; + } + + public void Insert(int index, string s) + { + if (s == null) + { + return; + } + + int count = s.Length; + + if (_pos > (_chars.Length - count)) + { + Grow(count); + } + + int remaining = _pos - index; + _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); + s.AsSpan().CopyTo(_chars.Slice(index)); + _pos += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char c) + { + int pos = _pos; + if ((uint)pos < (uint)_chars.Length) + { + _chars[pos] = c; + _pos = pos + 1; + } + else + { + GrowAndAppend(c); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string s) + { + if (s == null) + { + return; + } + + int pos = _pos; + if (s.Length == 1 && (uint)pos < (uint)_chars.Length) // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. + { + _chars[pos] = s[0]; + _pos = pos + 1; + } + else + { + AppendSlow(s); + } + } + + private void AppendSlow(string s) + { + int pos = _pos; + if (pos > _chars.Length - s.Length) + { + Grow(s.Length); + } + + s.AsSpan().CopyTo(_chars.Slice(pos)); + _pos += s.Length; + } + + public void Append(char c, int count) + { + if (_pos > _chars.Length - count) + { + Grow(count); + } + + Span dst = _chars.Slice(_pos, count); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = c; + } + _pos += count; + } + + public unsafe void Append(char* value, int length) + { + int pos = _pos; + if (pos > _chars.Length - length) + { + Grow(length); + } + + Span dst = _chars.Slice(_pos, length); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = *value++; + } + _pos += length; + } + + public void Append(ReadOnlySpan value) + { + int pos = _pos; + if (pos > _chars.Length - value.Length) + { + Grow(value.Length); + } + + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span AppendSpan(int length) + { + int origPos = _pos; + if (origPos > _chars.Length - length) + { + Grow(length); + } + + _pos = origPos + length; + return _chars.Slice(origPos, length); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowAndAppend(char c) + { + Grow(1); + Append(c); + } + + /// + /// Resize the internal buffer either by doubling current buffer size or + /// by adding to + /// whichever is greater. + /// + /// + /// Number of chars requested beyond current position. + /// + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow(int additionalCapacityBeyondPos) + { + Debug.Assert(additionalCapacityBeyondPos > 0); + Debug.Assert(_pos > _chars.Length - additionalCapacityBeyondPos, "Grow called incorrectly, no resize is needed."); + + char[] poolArray = ArrayPool.Shared.Rent(Math.Max(_pos + additionalCapacityBeyondPos, _chars.Length * 2)); + + _chars.Slice(0, _pos).CopyTo(poolArray); + + char[] toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = poolArray; + if (toReturn != null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + char[] toReturn = _arrayToReturnToPool; + this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again + if (toReturn != null) + { + ArrayPool.Shared.Return(toReturn); + } + } + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt deleted file mode 100644 index e6f3a703..00000000 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.tt +++ /dev/null @@ -1,57 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); - } - - - static string CreateParameterNames(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); - } -#> -using System; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { -<# for(var i = 2; i <= 16; i++) { #> - public void AppendMany<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) - { - int written; - -<# for(var j = 0; j < i; j++) { #> - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg<#= j #>)); - } - } - index += written; - -<# } #> - } - - public void AppendManyLine<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) - { - AppendMany(<#= CreateParameterNames(i) #>); - AppendNewLine(); - } - -<# } #> - } -} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs new file mode 100644 index 00000000..78c1169b --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs @@ -0,0 +1,5609 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { + public void Concat(T0 arg0) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0) + { + Concat(arg0); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1) + { + Concat(arg0, arg1); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2) + { + Concat(arg0, arg1, arg2); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + Concat(arg0, arg1, arg2, arg3); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + Concat(arg0, arg1, arg2, arg3, arg4); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + if (typeof(T12) == typeof(string)) + { + var s12 = Unsafe.As(ref arg12); + if (s12 != null) + { + TryGrow(s12.Length); + s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s12.Length; + } + } + else if (typeof(T12) == typeof(int)) + { + int written = 0; + + var i12 = Unsafe.As(ref arg12); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + if (typeof(T12) == typeof(string)) + { + var s12 = Unsafe.As(ref arg12); + if (s12 != null) + { + TryGrow(s12.Length); + s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s12.Length; + } + } + else if (typeof(T12) == typeof(int)) + { + int written = 0; + + var i12 = Unsafe.As(ref arg12); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + + if (typeof(T13) == typeof(string)) + { + var s13 = Unsafe.As(ref arg13); + if (s13 != null) + { + TryGrow(s13.Length); + s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s13.Length; + } + } + else if (typeof(T13) == typeof(int)) + { + int written = 0; + + var i13 = Unsafe.As(ref arg13); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + if (typeof(T12) == typeof(string)) + { + var s12 = Unsafe.As(ref arg12); + if (s12 != null) + { + TryGrow(s12.Length); + s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s12.Length; + } + } + else if (typeof(T12) == typeof(int)) + { + int written = 0; + + var i12 = Unsafe.As(ref arg12); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + + if (typeof(T13) == typeof(string)) + { + var s13 = Unsafe.As(ref arg13); + if (s13 != null) + { + TryGrow(s13.Length); + s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s13.Length; + } + } + else if (typeof(T13) == typeof(int)) + { + int written = 0; + + var i13 = Unsafe.As(ref arg13); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + + if (typeof(T14) == typeof(string)) + { + var s14 = Unsafe.As(ref arg14); + if (s14 != null) + { + TryGrow(s14.Length); + s14.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s14.Length; + } + } + else if (typeof(T14) == typeof(int)) + { + int written = 0; + + var i14 = Unsafe.As(ref arg14); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + if (typeof(T0) == typeof(string)) + { + var s0 = Unsafe.As(ref arg0); + if (s0 != null) + { + TryGrow(s0.Length); + s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s0.Length; + } + } + else if (typeof(T0) == typeof(int)) + { + int written = 0; + + var i0 = Unsafe.As(ref arg0); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + } + + if (typeof(T1) == typeof(string)) + { + var s1 = Unsafe.As(ref arg1); + if (s1 != null) + { + TryGrow(s1.Length); + s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s1.Length; + } + } + else if (typeof(T1) == typeof(int)) + { + int written = 0; + + var i1 = Unsafe.As(ref arg1); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg1)); + } + } + index += written; + } + + if (typeof(T2) == typeof(string)) + { + var s2 = Unsafe.As(ref arg2); + if (s2 != null) + { + TryGrow(s2.Length); + s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s2.Length; + } + } + else if (typeof(T2) == typeof(int)) + { + int written = 0; + + var i2 = Unsafe.As(ref arg2); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg2)); + } + } + index += written; + } + + if (typeof(T3) == typeof(string)) + { + var s3 = Unsafe.As(ref arg3); + if (s3 != null) + { + TryGrow(s3.Length); + s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s3.Length; + } + } + else if (typeof(T3) == typeof(int)) + { + int written = 0; + + var i3 = Unsafe.As(ref arg3); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg3)); + } + } + index += written; + } + + if (typeof(T4) == typeof(string)) + { + var s4 = Unsafe.As(ref arg4); + if (s4 != null) + { + TryGrow(s4.Length); + s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s4.Length; + } + } + else if (typeof(T4) == typeof(int)) + { + int written = 0; + + var i4 = Unsafe.As(ref arg4); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg4)); + } + } + index += written; + } + + if (typeof(T5) == typeof(string)) + { + var s5 = Unsafe.As(ref arg5); + if (s5 != null) + { + TryGrow(s5.Length); + s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s5.Length; + } + } + else if (typeof(T5) == typeof(int)) + { + int written = 0; + + var i5 = Unsafe.As(ref arg5); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg5)); + } + } + index += written; + } + + if (typeof(T6) == typeof(string)) + { + var s6 = Unsafe.As(ref arg6); + if (s6 != null) + { + TryGrow(s6.Length); + s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s6.Length; + } + } + else if (typeof(T6) == typeof(int)) + { + int written = 0; + + var i6 = Unsafe.As(ref arg6); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + } + + if (typeof(T7) == typeof(string)) + { + var s7 = Unsafe.As(ref arg7); + if (s7 != null) + { + TryGrow(s7.Length); + s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s7.Length; + } + } + else if (typeof(T7) == typeof(int)) + { + int written = 0; + + var i7 = Unsafe.As(ref arg7); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + } + + if (typeof(T8) == typeof(string)) + { + var s8 = Unsafe.As(ref arg8); + if (s8 != null) + { + TryGrow(s8.Length); + s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s8.Length; + } + } + else if (typeof(T8) == typeof(int)) + { + int written = 0; + + var i8 = Unsafe.As(ref arg8); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + } + + if (typeof(T9) == typeof(string)) + { + var s9 = Unsafe.As(ref arg9); + if (s9 != null) + { + TryGrow(s9.Length); + s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s9.Length; + } + } + else if (typeof(T9) == typeof(int)) + { + int written = 0; + + var i9 = Unsafe.As(ref arg9); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + } + + if (typeof(T10) == typeof(string)) + { + var s10 = Unsafe.As(ref arg10); + if (s10 != null) + { + TryGrow(s10.Length); + s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s10.Length; + } + } + else if (typeof(T10) == typeof(int)) + { + int written = 0; + + var i10 = Unsafe.As(ref arg10); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + } + + if (typeof(T11) == typeof(string)) + { + var s11 = Unsafe.As(ref arg11); + if (s11 != null) + { + TryGrow(s11.Length); + s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s11.Length; + } + } + else if (typeof(T11) == typeof(int)) + { + int written = 0; + + var i11 = Unsafe.As(ref arg11); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + } + + if (typeof(T12) == typeof(string)) + { + var s12 = Unsafe.As(ref arg12); + if (s12 != null) + { + TryGrow(s12.Length); + s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s12.Length; + } + } + else if (typeof(T12) == typeof(int)) + { + int written = 0; + + var i12 = Unsafe.As(ref arg12); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + } + + if (typeof(T13) == typeof(string)) + { + var s13 = Unsafe.As(ref arg13); + if (s13 != null) + { + TryGrow(s13.Length); + s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s13.Length; + } + } + else if (typeof(T13) == typeof(int)) + { + int written = 0; + + var i13 = Unsafe.As(ref arg13); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + } + + if (typeof(T14) == typeof(string)) + { + var s14 = Unsafe.As(ref arg14); + if (s14 != null) + { + TryGrow(s14.Length); + s14.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s14.Length; + } + } + else if (typeof(T14) == typeof(int)) + { + int written = 0; + + var i14 = Unsafe.As(ref arg14); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + } + + if (typeof(T15) == typeof(string)) + { + var s15 = Unsafe.As(ref arg15); + if (s15 != null) + { + TryGrow(s15.Length); + s15.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s15.Length; + } + } + else if (typeof(T15) == typeof(int)) + { + int written = 0; + + var i15 = Unsafe.As(ref arg15); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i15)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i15)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + } + + } + + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + AppendNewLine(); + } + + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.tt new file mode 100644 index 00000000..b0563c34 --- /dev/null +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.tt @@ -0,0 +1,86 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + } + + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + } +#> +using System; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { +<# for(var i = 1; i <= 16; i++) { #> + public void Concat<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) + { +<# for(var j = 0; j < i; j++) { #> + if (typeof(T<#= j #>) == typeof(string)) + { + var s<#= j #> = Unsafe.As, string>(ref arg<#= j #>); + if (s<#= j #> != null) + { + TryGrow(s<#= j #>.Length); + s<#= j #>.AsSpan().TryCopyTo(buffer.AsSpan(index)); + index += s<#= j#>.Length; + } + } + else if (typeof(T<#= j #>) == typeof(int)) + { + int written = 0; + + var i<#= j #> = Unsafe.As, int>(ref arg<#= j #>); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i<#= j #>)) + { + Grow(); + if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i<#= j #>)) + { + ThrowArgumentException(nameof(arg<#= j #>)); + } + } + index += written; + } + else + { + int written = 0; + + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + { + Grow(written); + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + { + ThrowArgumentException(nameof(arg<#= j #>)); + } + } + index += written; + } + +<# } #> + } + + public void ConcatLine<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) + { + Concat(<#= CreateParameterNames(i) #>); + AppendNewLine(); + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 54a422d6..4199c437 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -6,65 +6,65 @@ public partial struct Utf16ValueStringBuilder { static object CreateFormatter(Type type) { - if (type == typeof(System.Byte)) - { - return new TryFormat((System.Byte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.DateTime)) - { - return new TryFormat((System.DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); - } - if (type == typeof(System.DateTimeOffset)) + if (type == typeof(System.SByte)) { - return new TryFormat((System.DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.SByte x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Decimal)) + if (type == typeof(System.Int16)) { - return new TryFormat((System.Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int16 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Double)) + if (type == typeof(System.Int32)) { - return new TryFormat((System.Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int32 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Guid)) + if (type == typeof(System.Int64)) { - return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Int64 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Int16)) + if (type == typeof(System.Byte)) { - return new TryFormat((System.Int16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Byte x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Int32)) + if (type == typeof(System.UInt16)) { - return new TryFormat((System.Int32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt16 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.Int64)) + if (type == typeof(System.UInt32)) { - return new TryFormat((System.Int64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt32 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } - if (type == typeof(System.SByte)) + if (type == typeof(System.UInt64)) { - return new TryFormat((System.SByte x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.UInt64 x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); } if (type == typeof(System.Single)) { return new TryFormat((System.Single x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } + if (type == typeof(System.Double)) + { + return new TryFormat((System.Double x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } if (type == typeof(System.TimeSpan)) { return new TryFormat((System.TimeSpan x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(System.UInt16)) + if (type == typeof(System.DateTime)) { - return new TryFormat((System.UInt16 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.DateTime x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(System.UInt32)) + if (type == typeof(System.DateTimeOffset)) { - return new TryFormat((System.UInt32 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.DateTimeOffset x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(System.UInt64)) + if (type == typeof(System.Decimal)) { - return new TryFormat((System.UInt64 x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + return new TryFormat((System.Decimal x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); + } + if (type == typeof(System.Guid)) + { + return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } return null; diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt index b9947816..6925ef3c 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt @@ -5,24 +5,29 @@ <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> <# - var spanFormattables = new Type[] + var spanFormattablesA = new Type[] { - typeof(Byte), - typeof(DateTime), - typeof(DateTimeOffset), - typeof(Decimal), - typeof(Double), - typeof(Guid), + typeof(SByte), typeof(Int16), typeof(Int32), typeof(Int64), - typeof(SByte), - typeof(Single), - typeof(TimeSpan), + }; + var spanFormattablesB = new Type[] + { + typeof(Byte), typeof(UInt16), typeof(UInt32), typeof(UInt64), - // typeof(Version), + }; + var spanFormattablesC = new Type[] + { + typeof(Single), + typeof(Double), + typeof(TimeSpan), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(Decimal), + typeof(Guid), }; #> using System; @@ -33,7 +38,19 @@ namespace Cysharp.Text { static object CreateFormatter(Type type) { -<# foreach(var t in spanFormattables) { #> +<# foreach(var t in spanFormattablesA) { #> + if (type == typeof(<#= t.FullName #>)) + { + return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); + } +<# } #> +<# foreach(var t in spanFormattablesB) { #> + if (type == typeof(<#= t.FullName #>)) + { + return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan format) => format.Length == 0 ? FastNumberWriter.TryWriteUInt64(dest, out written, x) : x.TryFormat(dest, out written, format)); + } +<# } #> +<# foreach(var t in spanFormattablesC) { #> if (type == typeof(<#= t.FullName #>)) { return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 189383a4..c2181024 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -44,7 +44,8 @@ static Utf16ValueStringBuilder() public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); - internal void Init(bool disposeImmediately) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Utf16ValueStringBuilder(bool disposeImmediately) { char[] buf; if (disposeImmediately) @@ -64,6 +65,7 @@ internal void Init(bool disposeImmediately) index = 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (buffer.Length != ThreadStaticBufferSize) @@ -74,6 +76,11 @@ public void Dispose() index = 0; } + public void Clear() + { + index = 0; + } + void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) @@ -119,6 +126,24 @@ public void AppendNewLine() } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char value) + { + if (buffer.Length - index < 1) + { + Grow(1); + } + + buffer[index++] = value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(char value) + { + Append(value); + AppendNewLine(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { @@ -209,7 +234,7 @@ public static void RegisterTryFormat(TryFormat formatMethod) FormatterCache.TryFormatDelegate = formatMethod; } - static class FormatterCache + public static class FormatterCache { public static TryFormat TryFormatDelegate; static FormatterCache() @@ -221,6 +246,10 @@ static FormatterCache() { formatter = new TryFormat(EnumUtil.TryFormatUtf16); } + else if (typeof(T) == typeof(string)) + { + formatter = new TryFormat(TryFormatString); + } else { formatter = new TryFormat(TryFormatDefault); @@ -230,6 +259,21 @@ static FormatterCache() TryFormatDelegate = formatter; } + static bool TryFormatString(T value, Span dest, out int written, ReadOnlySpan format) + { + var s = value as string; + + if (s == null) + { + written = 0; + return true; + } + + // also use this length when result is false. + written = s.Length; + return s.AsSpan().TryCopyTo(dest); + } + static bool TryFormatDefault(T value, Span dest, out int written, ReadOnlySpan format) { if (value == null) diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs similarity index 59% rename from src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs rename to src/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs index e900deb4..4ee6f9c9 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs @@ -2,26 +2,50 @@ namespace Cysharp.Text { - public partial struct Utf16ValueStringBuilder + public partial struct Utf8ValueStringBuilder { - public void AppendMany(T0 arg0, T1 arg1) + public void Concat(T0 arg0) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + } + + public void ConcatLine(T0 arg0) + { + Concat(arg0); + AppendNewLine(); + } + + public void Concat(T0 arg0, T1 arg1) + { + int written; + var span = buffer.AsSpan(); + + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) + { + ThrowArgumentException(nameof(arg0)); + } + } + index += written; + + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } @@ -30,40 +54,41 @@ public void AppendMany(T0 arg0, T1 arg1) } - public void AppendManyLine(T0 arg0, T1 arg1) + public void ConcatLine(T0 arg0, T1 arg1) { - AppendMany(arg0, arg1); + Concat(arg0, arg1); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2) + public void Concat(T0 arg0, T1 arg1, T2 arg2) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } @@ -72,50 +97,51 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2) } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2) { - AppendMany(arg0, arg1, arg2); + Concat(arg0, arg1, arg2); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } @@ -124,60 +150,61 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { - AppendMany(arg0, arg1, arg2, arg3); + Concat(arg0, arg1, arg2, arg3); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } @@ -186,70 +213,71 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { - AppendMany(arg0, arg1, arg2, arg3, arg4); + Concat(arg0, arg1, arg2, arg3, arg4); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } @@ -258,80 +286,81 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5); + Concat(arg0, arg1, arg2, arg3, arg4, arg5); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } @@ -340,90 +369,91 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } @@ -432,100 +462,101 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } @@ -534,110 +565,111 @@ public void AppendMany(T0 arg0, T1 arg1, T2 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } @@ -646,120 +678,121 @@ public void AppendMany(T0 arg0, T1 arg1, } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } @@ -768,130 +801,131 @@ public void AppendMany(T0 arg0, T1 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } @@ -900,140 +934,141 @@ public void AppendMany(T0 arg0 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg12)); } @@ -1042,150 +1077,151 @@ public void AppendMany(T0 } - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg12)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg13)); } @@ -1194,160 +1230,161 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg12)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg13)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg14)); } @@ -1356,170 +1393,171 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); AppendNewLine(); } - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { int written; + var span = buffer.AsSpan(); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg0)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg1)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg2)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg3)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg4)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg5)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg6)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg7)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg8)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg9)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg10)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg11)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg12)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg13)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg14)); } } index += written; - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg15, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) + if (!FormatterCache.TryFormatDelegate(arg15, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg15)); } @@ -1528,9 +1566,9 @@ public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); AppendNewLine(); } diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.tt similarity index 76% rename from src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt rename to src/ZString/Utf8/Utf8ValueStringBuilder.Concat.tt index a3dbe717..6c314d20 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.tt @@ -27,16 +27,17 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder { -<# for(var i = 2; i <= 16; i++) { #> - public void AppendMany<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) +<# for(var i = 1; i <= 16; i++) { #> + public void Concat<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) { int written; + var span = buffer.AsSpan(); <# for(var j = 0; j < i; j++) { #> - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, span.Slice(index), out written, default)) { Grow(written); - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) + if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, span.Slice(index), out written, default)) { ThrowArgumentException(nameof(arg<#= j #>)); } @@ -46,9 +47,9 @@ namespace Cysharp.Text <# } #> } - public void AppendManyLine<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) + public void ConcatLine<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) { - AppendMany(<#= CreateParameterNames(i) #>); + Concat(<#= CreateParameterNames(i) #>); AppendNewLine(); } diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 522e53c4..935f38af 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -46,7 +46,8 @@ static Utf8ValueStringBuilder() public int Length => index; public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); - internal void Init(bool disposeImmediately) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Utf8ValueStringBuilder(bool disposeImmediately) { byte[] buf; if (disposeImmediately) @@ -66,6 +67,7 @@ internal void Init(bool disposeImmediately) index = 0; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (buffer.Length != ThreadStaticBufferSize) @@ -121,6 +123,29 @@ public void AppendNewLine() } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe void Append(char value) + { + var maxLen = UTF8NoBom.GetMaxByteCount(1); + if (buffer.Length - index < maxLen) + { + Grow(maxLen); + } + + fixed (byte* bp = &buffer[index]) + { + index += UTF8NoBom.GetBytes(&value, 1, bp, maxLen); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(char value) + { + Append(value); + AppendNewLine(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { diff --git a/src/ZString/ZString.Concat.cs b/src/ZString/ZString.Concat.cs new file mode 100644 index 00000000..a5535be2 --- /dev/null +++ b/src/ZString/ZString.Concat.cs @@ -0,0 +1,248 @@ +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public static partial class ZString + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + } +} \ No newline at end of file diff --git a/src/ZString/ZString.Concat.tt b/src/ZString/ZString.Concat.tt new file mode 100644 index 00000000..a669a454 --- /dev/null +++ b/src/ZString/ZString.Concat.tt @@ -0,0 +1,48 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + } + + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + } +#> +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public static partial class ZString + { +<# for(var i = 1; i <= 16; i++) { #> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Concat<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + sb.Concat(<#= CreateParameterNames(i) #>); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/ZString.Format.cs b/src/ZString/ZString.Format.cs index 2139423b..1860dae7 100644 --- a/src/ZString/ZString.Format.cs +++ b/src/ZString/ZString.Format.cs @@ -1,15 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Runtime.CompilerServices; namespace Cysharp.Text { public static partial class ZString { + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0); @@ -21,10 +19,10 @@ public static string Format(string format, T0 arg0) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1); @@ -36,10 +34,10 @@ public static string Format(string format, T0 arg0, T1 arg1) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2); @@ -51,10 +49,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2 } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3); @@ -66,10 +64,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); @@ -81,10 +79,10 @@ public static string Format(string format, T0 arg0, T1 arg1, } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); @@ -96,10 +94,10 @@ public static string Format(string format, T0 arg0, T1 a } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); @@ -111,10 +109,10 @@ public static string Format(string format, T0 arg0, } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); @@ -126,10 +124,10 @@ public static string Format(string format, T0 ar } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); @@ -141,10 +139,10 @@ public static string Format(string format, T } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); @@ -156,10 +154,10 @@ public static string Format(string forma } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); @@ -171,10 +169,10 @@ public static string Format(string } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); @@ -186,10 +184,10 @@ public static string Format(st } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); @@ -201,10 +199,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); @@ -216,10 +214,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); @@ -231,10 +229,10 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); diff --git a/src/ZString/ZString.Format.tt b/src/ZString/ZString.Format.tt index 16746f37..c0e32e88 100644 --- a/src/ZString/ZString.Format.tt +++ b/src/ZString/ZString.Format.tt @@ -21,19 +21,17 @@ return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); } #> -using System; -using System.Collections.Generic; -using System.Text; +using System.Runtime.CompilerServices; namespace Cysharp.Text { public static partial class ZString { <# for(var i = 1; i <= 16; i++) { #> + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { - var sb = new Utf16ValueStringBuilder(); - sb.Init(true); + var sb = new Utf16ValueStringBuilder(true); try { sb.AppendFormat(format, <#= CreateParameterNames(i) #>); diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 788cbaed..33c62086 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -1,19 +1,125 @@ -namespace Cysharp.Text +using System; +using System.Buffers; +using System.Collections.Generic; + +namespace Cysharp.Text { public static partial class ZString { public static Utf16ValueStringBuilder CreateStringBuilder() { - var builder = new Utf16ValueStringBuilder(); - builder.Init(false); - return builder; + return new Utf16ValueStringBuilder(false); } public static Utf8ValueStringBuilder CreateUtf8StringBuilder() { - var builder = new Utf8ValueStringBuilder(); - builder.Init(false); - return builder; + return new Utf8ValueStringBuilder(false); + } + + public static Utf16ValueStringBuilder CreateStringBuilder(bool notNested) + { + return new Utf16ValueStringBuilder(notNested); + } + + public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) + { + return new Utf8ValueStringBuilder(notNested); + } + + public static string Join(char separator, params T[] values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Join(char separator, IEnumerable values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + var isFirst = false; + foreach (var item in values) + { + if (!isFirst) + { + sb.Append(separator); + } + else + { + isFirst = true; + } + sb.Append(item); + } + + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Join(string separator, params T[] values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public static string Join(string separator, IEnumerable values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + var isFirst = false; + foreach (var item in values) + { + if (!isFirst) + { + sb.Append(separator); + } + else + { + isFirst = true; + } + sb.Append(item); + } + + return sb.ToString(); + } + finally + { + sb.Dispose(); + } } } } diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index f1d200c6..dea81e0a 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -36,6 +36,10 @@ Utf16ValueStringBuilder.AppendMany.cs TextTemplatingFileGenerator
+ + TextTemplatingFileGenerator + Utf16ValueStringBuilder.Concat.cs + Utf16ValueStringBuilder.CreateFormatter.cs TextTemplatingFileGenerator @@ -52,6 +56,10 @@ Utf8ValueStringBuilder.AppendMany.cs TextTemplatingFileGenerator + + TextTemplatingFileGenerator + Utf8ValueStringBuilder.Concat.cs + Utf8ValueStringBuilder.CreateFormatter.cs TextTemplatingFileGenerator @@ -64,6 +72,10 @@ TextTemplatingFileGenerator Utf16ValueStringBuilder.AppendFormat.cs + + TextTemplatingFileGenerator + ZString.Concat.cs + TextTemplatingFileGenerator ZString.Format.cs @@ -81,6 +93,11 @@ True True + + True + True + Utf16ValueStringBuilder.Concat.tt + Utf16ValueStringBuilder.CreateFormatter.tt True @@ -101,6 +118,11 @@ True Utf8ValueStringBuilder.AppendMany.tt + + True + True + Utf8ValueStringBuilder.Concat.tt + True True @@ -111,6 +133,11 @@ True Utf8ValueStringBuilder.SpanFormattableAppend.tt + + True + True + ZString.Concat.tt + True True diff --git a/tests/ZString.Tests/Primitives.cs b/tests/ZString.Tests/Primitives.cs index 8f65166c..f9e1914b 100644 --- a/tests/ZString.Tests/Primitives.cs +++ b/tests/ZString.Tests/Primitives.cs @@ -38,8 +38,8 @@ public void Integer(int x, int y) var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.AppendMany(x, y); - sb4.AppendMany(x, y); + sb3.Concat(x, y); + sb4.Concat(x, y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); @@ -74,8 +74,8 @@ public void UInt64(ulong x, ulong y) var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.AppendMany(x, y); - sb4.AppendMany(x, y); + sb3.Concat(x, y); + sb4.Concat(x, y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); @@ -110,8 +110,8 @@ public void Double(double x, double y) var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.AppendMany(x, y); - sb4.AppendMany(x, y); + sb3.Concat(x, y); + sb4.Concat(x, y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); @@ -143,8 +143,8 @@ public void Single(float x, float y) var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.AppendMany(x, y); - sb4.AppendMany(x, y); + sb3.Concat(x, y); + sb4.Concat(x, y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); @@ -170,8 +170,8 @@ public void Others() var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb1.Append(z); sb1.Append(g); //sb2.Append(x, StandardFormat.Parse("O")); sb2.Append(y, StandardFormat.Parse("O")); sb2.Append(z); sb2.Append(g); - sb3.AppendMany(x, y, z, g); - //sb4.AppendMany(x, y, z, g); + sb3.Concat(x, y, z, g); + //sb4.Concat(x, y, z, g); sb5.Append(x); sb5.Append(y); sb5.Append(z); sb5.Append(g); //sb1.ToString().Should().Be(sb2.ToString()); @@ -195,8 +195,8 @@ public void EnumTest() var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.AppendMany(x, y); - sb4.AppendMany(x, y); + sb3.Concat(x, y); + sb4.Concat(x, y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); From 4224b30a1677446c2c807e9ab7e66d4f88817d1f Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Thu, 13 Feb 2020 00:00:20 +0900 Subject: [PATCH 021/139] no compile error --- .../Scripts/ZString/FastNumberWriter.cs | 299 ++ .../Scripts/ZString/Number/BitOperations.cs | 284 ++ .../Assets/Scripts/ZString/Number/BufferEx.cs | 28 + .../Scripts/ZString/Number/DecimalEx.cs | 93 + .../Assets/Scripts/ZString/Number/FloatEx.cs | 43 + .../Scripts/ZString/Number/InternalSpanEx.cs | 237 ++ .../Assets/Scripts/ZString/Number/MathEx.cs | 263 ++ .../ZString/Number/Number.BigInteger.cs | 1222 ++++++++ .../Scripts/ZString/Number/Number.DiyFp.cs | 157 + .../Scripts/ZString/Number/Number.Dragon4.cs | 525 ++++ .../ZString/Number/Number.Formatting.cs | 2544 +++++++++++++++++ .../Scripts/ZString/Number/Number.Grisu3.cs | 1067 +++++++ .../ZString/Number/Number.NumberBuffer.cs | 124 + .../Number.NumberToFloatingPointBits.cs | 637 +++++ .../Scripts/ZString/Number/Number.Parsing.cs | 2028 +++++++++++++ .../ZString/Number/NumberFormatInfoEx.cs | 15 + .../ZString/Number/ValueStringBuilder.cs | 309 ++ src/ZString/Number/DecimalEx.cs | 55 +- src/ZString/Number/FormattingHelpers.cs | 138 + src/ZString/Number/MathEx.cs | 18 +- src/ZString/Number/Number.Formatting.cs | 55 +- src/ZString/ZString.csproj | 3 + 22 files changed, 10114 insertions(+), 30 deletions(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/FastNumberWriter.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/BitOperations.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/BufferEx.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/DecimalEx.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/FloatEx.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/InternalSpanEx.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/MathEx.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.BigInteger.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.DiyFp.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Dragon4.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Formatting.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Grisu3.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberBuffer.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberToFloatingPointBits.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Parsing.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/NumberFormatInfoEx.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/ValueStringBuilder.cs create mode 100644 src/ZString/Number/FormattingHelpers.cs diff --git a/src/ZString.Unity/Assets/Scripts/ZString/FastNumberWriter.cs b/src/ZString.Unity/Assets/Scripts/ZString/FastNumberWriter.cs new file mode 100644 index 00000000..bd84dd41 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/FastNumberWriter.cs @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + internal static class FastNumberWriter + { + // Faster than .NET Core .TryFormat without format string. + + public static bool TryWriteInt64(Span buffer, out int charsWritten, long value) + { + var offset = 0; + charsWritten = 0; + long num1 = value, num2, num3, num4, num5, div; + + if (value < 0) + { + if (value == long.MinValue) // -9223372036854775808 + { + if (buffer.Length < 20) { return false; } + buffer[offset++] = (char)'-'; + buffer[offset++] = (char)'9'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'2'; + buffer[offset++] = (char)'0'; + buffer[offset++] = (char)'3'; + buffer[offset++] = (char)'6'; + buffer[offset++] = (char)'8'; + buffer[offset++] = (char)'5'; + buffer[offset++] = (char)'4'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'7'; + buffer[offset++] = (char)'5'; + buffer[offset++] = (char)'8'; + buffer[offset++] = (char)'0'; + buffer[offset++] = (char)'8'; + charsWritten = offset; + return true; + } + + if (buffer.Length < 1) { return false; } + buffer[offset++] = (char)'-'; + num1 = unchecked(-value); + } + + // WriteUInt64(inlined) + + if (num1 < 10000) + { + if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } + if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } + if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } + if (buffer.Length < 4) { return false; } + goto L4; + } + else + { + num2 = num1 / 10000; + num1 -= num2 * 10000; + if (num2 < 10000) + { + if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } + if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } + if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } + if (buffer.Length < 8) { return false; } + goto L8; + } + else + { + num3 = num2 / 10000; + num2 -= num3 * 10000; + if (num3 < 10000) + { + if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } + if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } + if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } + if (buffer.Length < 12) { return false; } + goto L12; + } + else + { + num4 = num3 / 10000; + num3 -= num4 * 10000; + if (num4 < 10000) + { + if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } + if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } + if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } + if (buffer.Length < 16) { return false; } + goto L16; + } + else + { + num5 = num4 / 10000; + num4 -= num5 * 10000; + if (num5 < 10000) + { + if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } + if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } + if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } + if (buffer.Length < 20) { return false; } + goto L20; + } + L20: + buffer[offset++] = (char)('0' + (div = (num5 * 8389L) >> 23)); + num5 -= div * 1000; + L19: + buffer[offset++] = (char)('0' + (div = (num5 * 5243L) >> 19)); + num5 -= div * 100; + L18: + buffer[offset++] = (char)('0' + (div = (num5 * 6554L) >> 16)); + num5 -= div * 10; + L17: + buffer[offset++] = (char)('0' + (num5)); + } + L16: + buffer[offset++] = (char)('0' + (div = (num4 * 8389L) >> 23)); + num4 -= div * 1000; + L15: + buffer[offset++] = (char)('0' + (div = (num4 * 5243L) >> 19)); + num4 -= div * 100; + L14: + buffer[offset++] = (char)('0' + (div = (num4 * 6554L) >> 16)); + num4 -= div * 10; + L13: + buffer[offset++] = (char)('0' + (num4)); + } + L12: + buffer[offset++] = (char)('0' + (div = (num3 * 8389L) >> 23)); + num3 -= div * 1000; + L11: + buffer[offset++] = (char)('0' + (div = (num3 * 5243L) >> 19)); + num3 -= div * 100; + L10: + buffer[offset++] = (char)('0' + (div = (num3 * 6554L) >> 16)); + num3 -= div * 10; + L9: + buffer[offset++] = (char)('0' + (num3)); + } + L8: + buffer[offset++] = (char)('0' + (div = (num2 * 8389L) >> 23)); + num2 -= div * 1000; + L7: + buffer[offset++] = (char)('0' + (div = (num2 * 5243L) >> 19)); + num2 -= div * 100; + L6: + buffer[offset++] = (char)('0' + (div = (num2 * 6554L) >> 16)); + num2 -= div * 10; + L5: + buffer[offset++] = (char)('0' + (num2)); + } + L4: + buffer[offset++] = (char)('0' + (div = (num1 * 8389L) >> 23)); + num1 -= div * 1000; + L3: + buffer[offset++] = (char)('0' + (div = (num1 * 5243L) >> 19)); + num1 -= div * 100; + L2: + buffer[offset++] = (char)('0' + (div = (num1 * 6554L) >> 16)); + num1 -= div * 10; + L1: + buffer[offset++] = (char)('0' + (num1)); + + charsWritten = offset; + return true; + } + + public static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) + { + ulong num1 = value, num2, num3, num4, num5, div; + charsWritten = 0; + var offset = 0; + + if (num1 < 10000) + { + if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } + if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } + if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } + if (buffer.Length < 4) { return false; } + goto L4; + } + else + { + num2 = num1 / 10000; + num1 -= num2 * 10000; + if (num2 < 10000) + { + if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } + if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } + if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } + if (buffer.Length < 8) { return false; } + goto L8; + } + else + { + num3 = num2 / 10000; + num2 -= num3 * 10000; + if (num3 < 10000) + { + if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } + if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } + if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } + if (buffer.Length < 12) { return false; } + goto L12; + } + else + { + num4 = num3 / 10000; + num3 -= num4 * 10000; + if (num4 < 10000) + { + if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } + if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } + if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } + if (buffer.Length < 16) { return false; } + goto L16; + } + else + { + num5 = num4 / 10000; + num4 -= num5 * 10000; + if (num5 < 10000) + { + if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } + if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } + if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } + if (buffer.Length < 20) { return false; } + goto L20; + } + L20: + buffer[offset++] = (char)('0' + (div = (num5 * 8389UL) >> 23)); + num5 -= div * 1000; + L19: + buffer[offset++] = (char)('0' + (div = (num5 * 5243UL) >> 19)); + num5 -= div * 100; + L18: + buffer[offset++] = (char)('0' + (div = (num5 * 6554UL) >> 16)); + num5 -= div * 10; + L17: + buffer[offset++] = (char)('0' + (num5)); + } + L16: + buffer[offset++] = (char)('0' + (div = (num4 * 8389UL) >> 23)); + num4 -= div * 1000; + L15: + buffer[offset++] = (char)('0' + (div = (num4 * 5243UL) >> 19)); + num4 -= div * 100; + L14: + buffer[offset++] = (char)('0' + (div = (num4 * 6554UL) >> 16)); + num4 -= div * 10; + L13: + buffer[offset++] = (char)('0' + (num4)); + } + L12: + buffer[offset++] = (char)('0' + (div = (num3 * 8389UL) >> 23)); + num3 -= div * 1000; + L11: + buffer[offset++] = (char)('0' + (div = (num3 * 5243UL) >> 19)); + num3 -= div * 100; + L10: + buffer[offset++] = (char)('0' + (div = (num3 * 6554UL) >> 16)); + num3 -= div * 10; + L9: + buffer[offset++] = (char)('0' + (num3)); + } + L8: + buffer[offset++] = (char)('0' + (div = (num2 * 8389UL) >> 23)); + num2 -= div * 1000; + L7: + buffer[offset++] = (char)('0' + (div = (num2 * 5243UL) >> 19)); + num2 -= div * 100; + L6: + buffer[offset++] = (char)('0' + (div = (num2 * 6554UL) >> 16)); + num2 -= div * 10; + L5: + buffer[offset++] = (char)('0' + (num2)); + } + L4: + buffer[offset++] = (char)('0' + (div = (num1 * 8389UL) >> 23)); + num1 -= div * 1000; + L3: + buffer[offset++] = (char)('0' + (div = (num1 * 5243UL) >> 19)); + num1 -= div * 100; + L2: + buffer[offset++] = (char)('0' + (div = (num1 * 6554UL) >> 16)); + num1 -= div * 10; + L1: + buffer[offset++] = (char)('0' + (num1)); + + charsWritten = offset; + return true; + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/BitOperations.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/BitOperations.cs new file mode 100644 index 00000000..978a99cb --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/BitOperations.cs @@ -0,0 +1,284 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Some routines inspired by the Stanford Bit Twiddling Hacks by Sean Eron Anderson: +// http://graphics.stanford.edu/~seander/bithacks.html + +namespace System.Numerics +{ + /// + /// Utility methods for intrinsic bit-twiddling operations. + /// The methods use hardware intrinsics when available on the underlying platform, + /// otherwise they use optimized software fallbacks. + /// + public static class BitOperations + { + // C# no-alloc optimization that directly wraps the data section of the dll (similar to string constants) + // https://github.com/dotnet/roslyn/pull/24621 + + private static ReadOnlySpan TrailingZeroCountDeBruijn => new byte[32] + { + 00, 01, 28, 02, 29, 14, 24, 03, + 30, 22, 20, 15, 25, 17, 04, 08, + 31, 27, 13, 23, 21, 19, 16, 07, + 26, 12, 18, 06, 11, 05, 10, 09 + }; + + private static ReadOnlySpan Log2DeBruijn => new byte[32] + { + 00, 09, 01, 10, 13, 21, 02, 29, + 11, 14, 16, 18, 22, 25, 03, 30, + 08, 12, 20, 28, 15, 17, 24, 07, + 19, 27, 23, 06, 26, 05, 04, 31 + }; + + /// + /// Count the number of leading zero bits in a mask. + /// Similar in behavior to the x86 instruction LZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LeadingZeroCount(uint value) + { + // Unguarded fallback contract is 0->31 + if (value == 0) + { + return 32; + } + + return 31 - Log2SoftwareFallback(value); + } + + /// + /// Count the number of leading zero bits in a mask. + /// Similar in behavior to the x86 instruction LZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LeadingZeroCount(ulong value) + { + uint hi = (uint)(value >> 32); + + if (hi == 0) + { + return 32 + LeadingZeroCount((uint)value); + } + + return LeadingZeroCount(hi); + } + + /// + /// Returns the integer (floor) log of the specified value, base 2. + /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Log2(uint value) + { + // Fallback contract is 0->0 + return Log2SoftwareFallback(value); + } + + /// + /// Returns the integer (floor) log of the specified value, base 2. + /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Log2(ulong value) + { + uint hi = (uint)(value >> 32); + + if (hi == 0) + { + return Log2((uint)value); + } + + return 32 + Log2(hi); + } + + /// + /// Returns the integer (floor) log of the specified value, base 2. + /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. + /// Does not directly use any hardware intrinsics, nor does it incur branching. + /// + /// The value. + private static int Log2SoftwareFallback(uint value) + { + // No AggressiveInlining due to large method size + // Has conventional contract 0->0 (Log(0) is undefined) + + // Fill trailing zeros with ones, eg 00010010 becomes 00011111 + value |= value >> 01; + value |= value >> 02; + value |= value >> 04; + value |= value >> 08; + value |= value >> 16; + + // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check + return Unsafe.AddByteOffset( + // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_1100_0100_1010_1100_1101_1101u + ref MemoryMarshal.GetReference(Log2DeBruijn), + // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here + (IntPtr)(int)((value * 0x07C4ACDDu) >> 27)); + } + + /// + /// Returns the population count (number of bits set) of a mask. + /// Similar in behavior to the x86 instruction POPCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int PopCount(uint value) + { + const uint c1 = 0x_55555555u; + const uint c2 = 0x_33333333u; + const uint c3 = 0x_0F0F0F0Fu; + const uint c4 = 0x_01010101u; + + value -= (value >> 1) & c1; + value = (value & c2) + ((value >> 2) & c2); + value = (((value + (value >> 4)) & c3) * c4) >> 24; + + return (int)value; + } + + /// + /// Returns the population count (number of bits set) of a mask. + /// Similar in behavior to the x86 instruction POPCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int PopCount(ulong value) + { + if (IntPtr.Size == 4) + { + return PopCount((uint)value) // lo + + PopCount((uint)(value >> 32)); // hi + } + else + { + const ulong c1 = 0x_55555555_55555555ul; + const ulong c2 = 0x_33333333_33333333ul; + const ulong c3 = 0x_0F0F0F0F_0F0F0F0Ful; + const ulong c4 = 0x_01010101_01010101ul; + + value -= (value >> 1) & c1; + value = (value & c2) + ((value >> 2) & c2); + value = (((value + (value >> 4)) & c3) * c4) >> 56; + + return (int)value; + } + } + + /// + /// Count the number of trailing zero bits in an integer value. + /// Similar in behavior to the x86 instruction TZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TrailingZeroCount(int value) + => TrailingZeroCount((uint)value); + + /// + /// Count the number of trailing zero bits in an integer value. + /// Similar in behavior to the x86 instruction TZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TrailingZeroCount(uint value) + { + // Unguarded fallback contract is 0->0 + if (value == 0) + { + return 32; + } + + // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check + return Unsafe.AddByteOffset( + // Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_0111_1100_1011_0101_0011_0001u + ref MemoryMarshal.GetReference(TrailingZeroCountDeBruijn), + // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here + (IntPtr)(int)(((value & (uint)-(int)value) * 0x077CB531u) >> 27)); // Multi-cast mitigates redundant conv.u8 + } + + /// + /// Count the number of trailing zero bits in a mask. + /// Similar in behavior to the x86 instruction TZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TrailingZeroCount(long value) + => TrailingZeroCount((ulong)value); + + /// + /// Count the number of trailing zero bits in a mask. + /// Similar in behavior to the x86 instruction TZCNT. + /// + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int TrailingZeroCount(ulong value) + { + uint lo = (uint)value; + + if (lo == 0) + { + return 32 + TrailingZeroCount((uint)(value >> 32)); + } + + return TrailingZeroCount(lo); + } + + /// + /// Rotates the specified value left by the specified number of bits. + /// Similar in behavior to the x86 instruction ROL. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..31] is treated as congruent mod 32. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint RotateLeft(uint value, int offset) + => (value << offset) | (value >> (32 - offset)); + + /// + /// Rotates the specified value left by the specified number of bits. + /// Similar in behavior to the x86 instruction ROL. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..63] is treated as congruent mod 64. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong RotateLeft(ulong value, int offset) + => (value << offset) | (value >> (64 - offset)); + + /// + /// Rotates the specified value right by the specified number of bits. + /// Similar in behavior to the x86 instruction ROR. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..31] is treated as congruent mod 32. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint RotateRight(uint value, int offset) + => (value >> offset) | (value << (32 - offset)); + + /// + /// Rotates the specified value right by the specified number of bits. + /// Similar in behavior to the x86 instruction ROR. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..63] is treated as congruent mod 64. + /// The rotated value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong RotateRight(ulong value, int offset) + => (value >> offset) | (value << (64 - offset)); + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/BufferEx.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/BufferEx.cs new file mode 100644 index 00000000..0b96bda3 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/BufferEx.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace System +{ + internal static class BufferEx + { + internal static unsafe void ZeroMemory(byte* dest, uint len) + { + if (len == 0) return; + + for (int i = 0; i < len; i++) + { + dest[i] = 0; + } + } + + internal static unsafe void Memcpy(byte* dest, byte* src, int len) + { + if (len == 0) return; + for (int i = 0; i < len; i++) + { + dest[i] = src[i]; + } + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/DecimalEx.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/DecimalEx.cs new file mode 100644 index 00000000..95125476 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/DecimalEx.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace System +{ + internal static class DecimalEx + { + [StructLayout(LayoutKind.Explicit)] + private struct DecimalBits + { + [FieldOffset(0)] + public int flags; + [FieldOffset(4)] + public int hi; + [FieldOffset(8)] + public int lo; + [FieldOffset(12)] + public int mid; + } + + [StructLayout(LayoutKind.Explicit)] + private struct DecCalc + { + private const uint TenToPowerNine = 1000000000; + + // NOTE: Do not change the offsets of these fields. This structure must have the same layout as Decimal. + [FieldOffset(0)] + public uint uflags; + [FieldOffset(4)] + public uint uhi; + [FieldOffset(8)] + public uint ulo; + [FieldOffset(12)] + public uint umid; + + /// + /// The low and mid fields combined in little-endian order + /// + [FieldOffset(8)] + private ulong ulomidLE; + + internal static uint DecDivMod1E9(ref DecCalc value) + { + ulong high64 = ((ulong)value.uhi << 32) + value.umid; + ulong div64 = high64 / TenToPowerNine; + value.uhi = (uint)(div64 >> 32); + value.umid = (uint)div64; + + ulong num = ((high64 - (uint)div64 * TenToPowerNine) << 32) + value.ulo; + uint div = (uint)(num / TenToPowerNine); + value.ulo = div; + return (uint)num - div * TenToPowerNine; + } + } + + private const int ScaleShift = 16; + + static ref DecCalc AsMutable(ref decimal d) => ref Unsafe.As(ref d); + + internal static uint High(this decimal value) + { + return Unsafe.As(ref value).uhi; + } + + internal static uint Low(this decimal value) + { + return Unsafe.As(ref value).ulo; + } + + internal static uint Mid(this decimal value) + { + return Unsafe.As(ref value).umid; + } + + internal static bool IsNegative(this decimal value) + { + return Unsafe.As(ref value).flags < 0; + } + + internal static int Scale(this decimal value) + { + return (byte)(Unsafe.As(ref value).flags >> ScaleShift); + } + + internal static uint DecDivMod1E9(ref decimal value) + { + return DecCalc.DecDivMod1E9(ref AsMutable(ref value)); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/FloatEx.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/FloatEx.cs new file mode 100644 index 00000000..bdc9280f --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/FloatEx.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace System +{ + internal static class FloatEx + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsFinite(double d) + { + long bits = BitConverter.DoubleToInt64Bits(d); + return (bits & 0x7FFFFFFFFFFFFFFF) < 0x7FF0000000000000; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsNegative(double d) + { + return BitConverter.DoubleToInt64Bits(d) < 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsFinite(float f) + { + int bits = SingleToInt32Bits(f); + return (bits & 0x7FFFFFFF) < 0x7F800000; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsNegative(float f) + { + return SingleToInt32Bits(f) < 0; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe int SingleToInt32Bits(float value) + { + return *((int*)&value); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/InternalSpanEx.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/InternalSpanEx.cs new file mode 100644 index 00000000..326bc0c7 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/InternalSpanEx.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace System +{ + internal static class InternalSpanEx + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool EqualsOrdinalIgnoreCase(this ReadOnlySpan span, ReadOnlySpan value) + { + if (span.Length != value.Length) + return false; + if (value.Length == 0) // span.Length == value.Length == 0 + return true; + + + + return EqualsOrdinalIgnoreCase(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), span.Length); + } + + static bool EqualsOrdinalIgnoreCase(ref char charA, ref char charB, int length) + { + IntPtr byteOffset = IntPtr.Zero; + + if (IntPtr.Size == 8) + { + // Read 4 chars (64 bits) at a time from each string + while ((uint)length >= 4) + { + ulong valueA = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charA, byteOffset))); + ulong valueB = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charB, byteOffset))); + + // A 32-bit test - even with the bit-twiddling here - is more efficient than a 64-bit test. + ulong temp = valueA | valueB; + if (!AllCharsInUInt32AreAscii((uint)temp | (uint)(temp >> 32))) + { + goto NonAscii; // one of the inputs contains non-ASCII data + } + + // Generally, the caller has likely performed a first-pass check that the input strings + // are likely equal. Consider a dictionary which computes the hash code of its key before + // performing a proper deep equality check of the string contents. We want to optimize for + // the case where the equality check is likely to succeed, which means that we want to avoid + // branching within this loop unless we're about to exit the loop, either due to failure or + // due to us running out of input data. + + if (!UInt64OrdinalIgnoreCaseAscii(valueA, valueB)) + { + return false; + } + + byteOffset += 8; + length -= 4; + } + } + + // Read 2 chars (32 bits) at a time from each string + while ((uint)length >= 2) + { + uint valueA = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charA, byteOffset))); + uint valueB = Unsafe.ReadUnaligned(ref Unsafe.As(ref Unsafe.AddByteOffset(ref charB, byteOffset))); + + if (!AllCharsInUInt32AreAscii(valueA | valueB)) + { + goto NonAscii; // one of the inputs contains non-ASCII data + } + + // Generally, the caller has likely performed a first-pass check that the input strings + // are likely equal. Consider a dictionary which computes the hash code of its key before + // performing a proper deep equality check of the string contents. We want to optimize for + // the case where the equality check is likely to succeed, which means that we want to avoid + // branching within this loop unless we're about to exit the loop, either due to failure or + // due to us running out of input data. + + if (!UInt32OrdinalIgnoreCaseAscii(valueA, valueB)) + { + return false; + } + + byteOffset += 4; + length -= 2; + } + + if (length != 0) + { + Debug.Assert(length == 1); + + uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset); + uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset); + + if ((valueA | valueB) > 0x7Fu) + { + goto NonAscii; // one of the inputs contains non-ASCII data + } + + if (valueA == valueB) + { + return true; // exact match + } + + valueA |= 0x20u; + if ((uint)(valueA - 'a') > (uint)('z' - 'a')) + { + return false; // not exact match, and first input isn't in [A-Za-z] + } + + // The ternary operator below seems redundant but helps RyuJIT generate more optimal code. + // See https://github.com/dotnet/coreclr/issues/914. + return (valueA == (valueB | 0x20u)) ? true : false; + } + + Debug.Assert(length == 0); + return true; + + NonAscii: + // The non-ASCII case is factored out into its own helper method so that the JIT + // doesn't need to emit a complex prolog for its caller (this method). + return EqualsOrdinalIgnoreCaseNonAscii(ref Unsafe.AddByteOffset(ref charA, byteOffset), ref Unsafe.AddByteOffset(ref charB, byteOffset), length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool AllCharsInUInt32AreAscii(uint value) + { + return (value & ~0x007F_007Fu) == 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool AllCharsInUInt64AreAscii(ulong value) + { + return (value & ~0x007F_007F_007F_007Ful) == 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool UInt32OrdinalIgnoreCaseAscii(uint valueA, uint valueB) + { + // ASSUMPTION: Caller has validated that input values are ASCII. + Debug.Assert(AllCharsInUInt32AreAscii(valueA)); + Debug.Assert(AllCharsInUInt32AreAscii(valueB)); + + // a mask of all bits which are different between A and B + uint differentBits = valueA ^ valueB; + + // the 0x80 bit of each word of 'lowerIndicator' will be set iff the word has value < 'A' + uint lowerIndicator = valueA + 0x0100_0100u - 0x0041_0041u; + + // the 0x80 bit of each word of 'upperIndicator' will be set iff (word | 0x20) has value > 'z' + uint upperIndicator = (valueA | 0x0020_0020u) + 0x0080_0080u - 0x007B_007Bu; + + // the 0x80 bit of each word of 'combinedIndicator' will be set iff the word is *not* [A-Za-z] + uint combinedIndicator = lowerIndicator | upperIndicator; + + // Shift all the 0x80 bits of 'combinedIndicator' into the 0x20 positions, then set all bits + // aside from 0x20. This creates a mask where all bits are set *except* for the 0x20 bits + // which correspond to alpha chars (either lower or upper). For these alpha chars only, the + // 0x20 bit is allowed to differ between the two input values. Every other char must be an + // exact bitwise match between the two input values. In other words, (valueA & mask) will + // convert valueA to uppercase, so (valueA & mask) == (valueB & mask) answers "is the uppercase + // form of valueA equal to the uppercase form of valueB?" (Technically if valueA has an alpha + // char in the same position as a non-alpha char in valueB, or vice versa, this operation will + // result in nonsense, but it'll still compute as inequal regardless, which is what we want ultimately.) + // The line below is a more efficient way of doing the same check taking advantage of the XOR + // computation we performed at the beginning of the method. + + return (((combinedIndicator >> 2) | ~0x0020_0020u) & differentBits) == 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool UInt64OrdinalIgnoreCaseAscii(ulong valueA, ulong valueB) + { + // ASSUMPTION: Caller has validated that input values are ASCII. + Debug.Assert(AllCharsInUInt64AreAscii(valueA)); + Debug.Assert(AllCharsInUInt64AreAscii(valueB)); + + // the 0x80 bit of each word of 'lowerIndicator' will be set iff the word has value >= 'A' + ulong lowerIndicator = valueA + 0x0080_0080_0080_0080ul - 0x0041_0041_0041_0041ul; + + // the 0x80 bit of each word of 'upperIndicator' will be set iff (word | 0x20) has value <= 'z' + ulong upperIndicator = (valueA | 0x0020_0020_0020_0020ul) + 0x0100_0100_0100_0100ul - 0x007B_007B_007B_007Bul; + + // the 0x20 bit of each word of 'combinedIndicator' will be set iff the word is [A-Za-z] + ulong combinedIndicator = (0x0080_0080_0080_0080ul & lowerIndicator & upperIndicator) >> 2; + + // Convert both values to lowercase (using the combined indicator from the first value) + // and compare for equality. It's possible that the first value will contain an alpha character + // where the second value doesn't (or vice versa), and applying the combined indicator will + // create nonsensical data, but the comparison would have failed anyway in this case so it's + // a safe operation to perform. + // + // This 64-bit method is similar to the 32-bit method, but it performs the equivalent of convert-to- + // lowercase-then-compare rather than convert-to-uppercase-and-compare. This particular operation + // happens to be faster on x64. + + return (valueA | combinedIndicator) == (valueB | combinedIndicator); + } + + private static bool EqualsOrdinalIgnoreCaseNonAscii(ref char charA, ref char charB, int length) + { + //if (!GlobalizationMode.Invariant) + //{ + // return CompareStringOrdinalIgnoreCase(ref charA, length, ref charB, length) == 0; + //} + //else + { + // If we don't have localization tables to consult, we'll still perform a case-insensitive + // check for ASCII characters, but if we see anything outside the ASCII range we'll immediately + // fail if it doesn't have true bitwise equality. + + IntPtr byteOffset = IntPtr.Zero; + while (length != 0) + { + // Ordinal equals or lowercase equals if the result ends up in the a-z range + uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset); + uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset); + + if (valueA == valueB || + ((valueA | 0x20) == (valueB | 0x20) && + (uint)((valueA | 0x20) - 'a') <= (uint)('z' - 'a'))) + { + byteOffset += 2; + length--; + } + else + { + return false; + } + } + + return true; + } + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/MathEx.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/MathEx.cs new file mode 100644 index 00000000..b3a047c9 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/MathEx.cs @@ -0,0 +1,263 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace System +{ + internal static class MathEx + { + public static uint DivRem(uint a, uint b, out uint result) + { + uint div = a / b; + result = a - (div * b); + return div; + } + + public static ulong DivRem(ulong a, ulong b, out ulong result) + { + ulong div = a / b; + result = a - (div * b); + return div; + } + + public static int DivRem(int a, int b, out int result) + { + int div = a / b; + result = a - (div * b); + return div; + } + + public static long DivRem(long a, long b, out long result) + { + long div = a / b; + result = a - (div * b); + return div; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte Clamp(byte value, byte min, byte max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static decimal Clamp(decimal value, decimal min, decimal max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double Clamp(double value, double min, double max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static short Clamp(short value, short min, short max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Clamp(int value, int min, int max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long Clamp(long value, long min, long max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static sbyte Clamp(sbyte value, sbyte min, sbyte max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Clamp(float value, float min, float max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort Clamp(ushort value, ushort min, ushort max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Clamp(uint value, uint min, uint max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong Clamp(ulong value, ulong min, ulong max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + private static void ThrowMinMaxException(T min, T max) + { + throw new ArgumentException($"Argument_MinMaxValue, min:{min} max:{max}"); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.BigInteger.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.BigInteger.cs new file mode 100644 index 00000000..686367d0 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.BigInteger.cs @@ -0,0 +1,1222 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System +{ + internal static partial class Number + { + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal unsafe ref struct BigInteger + { + // The longest binary mantissa requires: explicit mantissa bits + abs(min exponent) + // * Half: 10 + 14 = 24 + // * Single: 23 + 126 = 149 + // * Double: 52 + 1022 = 1074 + // * Quad: 112 + 16382 = 16494 + private const int BitsForLongestBinaryMantissa = 1074; + + // The longest digit sequence requires: ceil(log2(pow(10, max significant digits + 1 rounding digit))) + // * Half: ceil(log2(pow(10, 21 + 1))) = 74 + // * Single: ceil(log2(pow(10, 112 + 1))) = 376 + // * Double: ceil(log2(pow(10, 767 + 1))) = 2552 + // * Quad: ceil(log2(pow(10, 11563 + 1))) = 38415 + private const int BitsForLongestDigitSequence = 2552; + + // We require BitsPerBlock additional bits for shift space used during the pre-division preparation + private const int MaxBits = BitsForLongestBinaryMantissa + BitsForLongestDigitSequence + BitsPerBlock; + + private const int BitsPerBlock = sizeof(int) * 8; + private const int MaxBlockCount = (MaxBits + (BitsPerBlock - 1)) / BitsPerBlock; + + private static readonly uint[] s_Pow10UInt32Table = new uint[] + { + 1, // 10^0 + 10, // 10^1 + 100, // 10^2 + 1000, // 10^3 + 10000, // 10^4 + 100000, // 10^5 + 1000000, // 10^6 + 10000000, // 10^7 + }; + + private static readonly int[] s_Pow10BigNumTableIndices = new int[] + { + 0, // 10^8 + 2, // 10^16 + 5, // 10^32 + 10, // 10^64 + 18, // 10^128 + 33, // 10^256 + 61, // 10^512 + 116, // 10^1024 + }; + + private static readonly uint[] s_Pow10BigNumTable = new uint[] + { + // 10^8 + 1, // _length + 100000000, // _blocks + + // 10^16 + 2, // _length + 0x6FC10000, // _blocks + 0x002386F2, + + // 10^32 + 4, // _length + 0x00000000, // _blocks + 0x85ACEF81, + 0x2D6D415B, + 0x000004EE, + + // 10^64 + 7, // _length + 0x00000000, // _blocks + 0x00000000, + 0xBF6A1F01, + 0x6E38ED64, + 0xDAA797ED, + 0xE93FF9F4, + 0x00184F03, + + // 10^128 + 14, // _length + 0x00000000, // _blocks + 0x00000000, + 0x00000000, + 0x00000000, + 0x2E953E01, + 0x03DF9909, + 0x0F1538FD, + 0x2374E42F, + 0xD3CFF5EC, + 0xC404DC08, + 0xBCCDB0DA, + 0xA6337F19, + 0xE91F2603, + 0x0000024E, + + // 10^256 + 27, // _length + 0x00000000, // _blocks + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x982E7C01, + 0xBED3875B, + 0xD8D99F72, + 0x12152F87, + 0x6BDE50C6, + 0xCF4A6E70, + 0xD595D80F, + 0x26B2716E, + 0xADC666B0, + 0x1D153624, + 0x3C42D35A, + 0x63FF540E, + 0xCC5573C0, + 0x65F9EF17, + 0x55BC28F2, + 0x80DCC7F7, + 0xF46EEDDC, + 0x5FDCEFCE, + 0x000553F7, + + // 10^512 + 54, // _length + 0x00000000, // _blocks + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xFC6CF801, + 0x77F27267, + 0x8F9546DC, + 0x5D96976F, + 0xB83A8A97, + 0xC31E1AD9, + 0x46C40513, + 0x94E65747, + 0xC88976C1, + 0x4475B579, + 0x28F8733B, + 0xAA1DA1BF, + 0x703ED321, + 0x1E25CFEA, + 0xB21A2F22, + 0xBC51FB2E, + 0x96E14F5D, + 0xBFA3EDAC, + 0x329C57AE, + 0xE7FC7153, + 0xC3FC0695, + 0x85A91924, + 0xF95F635E, + 0xB2908EE0, + 0x93ABADE4, + 0x1366732A, + 0x9449775C, + 0x69BE5B0E, + 0x7343AFAC, + 0xB099BC81, + 0x45A71D46, + 0xA2699748, + 0x8CB07303, + 0x8A0B1F13, + 0x8CAB8A97, + 0xC1D238D9, + 0x633415D4, + 0x0000001C, + + // 10^1024 + 107, // _length + 0x00000000, // _blocks + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x2919F001, + 0xF55B2B72, + 0x6E7C215B, + 0x1EC29F86, + 0x991C4E87, + 0x15C51A88, + 0x140AC535, + 0x4C7D1E1A, + 0xCC2CD819, + 0x0ED1440E, + 0x896634EE, + 0x7DE16CFB, + 0x1E43F61F, + 0x9FCE837D, + 0x231D2B9C, + 0x233E55C7, + 0x65DC60D7, + 0xF451218B, + 0x1C5CD134, + 0xC9635986, + 0x922BBB9F, + 0xA7E89431, + 0x9F9F2A07, + 0x62BE695A, + 0x8E1042C4, + 0x045B7A74, + 0x1ABE1DE3, + 0x8AD822A5, + 0xBA34C411, + 0xD814B505, + 0xBF3FDEB3, + 0x8FC51A16, + 0xB1B896BC, + 0xF56DEEEC, + 0x31FB6BFD, + 0xB6F4654B, + 0x101A3616, + 0x6B7595FB, + 0xDC1A47FE, + 0x80D98089, + 0x80BDA5A5, + 0x9A202882, + 0x31EB0F66, + 0xFC8F1F90, + 0x976A3310, + 0xE26A7B7E, + 0xDF68368A, + 0x3CE3A0B8, + 0x8E4262CE, + 0x75A351A2, + 0x6CB0B6C9, + 0x44597583, + 0x31B5653F, + 0xC356E38A, + 0x35FAABA6, + 0x0190FBA0, + 0x9FC4ED52, + 0x88BC491B, + 0x1640114A, + 0x005B8041, + 0xF4F3235E, + 0x1E8D4649, + 0x36A8DE06, + 0x73C55349, + 0xA7E6BD2A, + 0xC1A6970C, + 0x47187094, + 0xD2DB49EF, + 0x926C3F5B, + 0xAE6209D4, + 0x2D433949, + 0x34F4A3C6, + 0xD4305D94, + 0xD9D61A05, + 0x00000325, + + // 9 Trailing blocks to ensure MaxBlockCount + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }; + + private int _length; + private fixed uint _blocks[MaxBlockCount]; + + public static void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result) + { + // determine which operand has the smaller length + ref BigInteger large = ref (lhs._length < rhs._length) ? ref rhs : ref lhs; + ref BigInteger small = ref (lhs._length < rhs._length) ? ref lhs : ref rhs; + + int largeLength = large._length; + int smallLength = small._length; + + // The output will be at least as long as the largest input + result._length = largeLength; + + // Add each block and add carry the overflow to the next block + ulong carry = 0; + + int largeIndex = 0; + int smallIndex = 0; + int resultIndex = 0; + + while (smallIndex < smallLength) + { + ulong sum = carry + large._blocks[largeIndex] + small._blocks[smallIndex]; + carry = sum >> 32; + result._blocks[resultIndex] = (uint)(sum); + + largeIndex++; + smallIndex++; + resultIndex++; + } + + // Add the carry to any blocks that only exist in the large operand + while (largeIndex < largeLength) + { + ulong sum = carry + large._blocks[largeIndex]; + carry = sum >> 32; + result._blocks[resultIndex] = (uint)(sum); + + largeIndex++; + resultIndex++; + } + + // If there's still a carry, append a new block + if (carry != 0) + { + Debug.Assert(carry == 1); + Debug.Assert((resultIndex == largeLength) && (largeLength < MaxBlockCount)); + + result._blocks[resultIndex] = 1; + result._length++; + } + } + + public static int Compare(ref BigInteger lhs, ref BigInteger rhs) + { + Debug.Assert(unchecked((uint)(lhs._length)) <= MaxBlockCount); + Debug.Assert(unchecked((uint)(rhs._length)) <= MaxBlockCount); + + int lhsLength = lhs._length; + int rhsLength = rhs._length; + + int lengthDelta = (lhsLength - rhsLength); + + if (lengthDelta != 0) + { + return lengthDelta; + } + + if (lhsLength == 0) + { + Debug.Assert(rhsLength == 0); + return 0; + } + + for (int index = (lhsLength - 1); index >= 0; index--) + { + long delta = (long)(lhs._blocks[index]) - rhs._blocks[index]; + + if (delta != 0) + { + return delta > 0 ? 1 : -1; + } + } + + return 0; + } + + public static uint CountSignificantBits(uint value) + { + return 32 - (uint)BitOperations.LeadingZeroCount(value); + } + + public static uint CountSignificantBits(ulong value) + { + return 64 - (uint)BitOperations.LeadingZeroCount(value); + } + + public static uint CountSignificantBits(ref BigInteger value) + { + if (value.IsZero()) + { + return 0; + } + + // We don't track any unused blocks, so we only need to do a BSR on the + // last index and add that to the number of bits we skipped. + + uint lastIndex = (uint)(value._length - 1); + return (lastIndex * BitsPerBlock) + CountSignificantBits(value._blocks[lastIndex]); + } + + public static void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger quo, out BigInteger rem) + { + // This is modified from the libraries BigIntegerCalculator.DivRem.cs implementation: + // https://github.com/dotnet/runtime/blob/master/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs + + Debug.Assert(!rhs.IsZero()); + + if (lhs.IsZero()) + { + SetZero(out quo); + SetZero(out rem); + return; + } + + int lhsLength = lhs._length; + int rhsLength = rhs._length; + + if ((lhsLength == 1) && (rhsLength == 1)) + { + uint quotient = MathEx.DivRem(lhs._blocks[0], rhs._blocks[0], out uint remainder); + SetUInt32(out quo, quotient); + SetUInt32(out rem, remainder); + return; + } + + if (rhsLength == 1) + { + // We can make the computation much simpler if the rhs is only one block + + int quoLength = lhsLength; + + ulong rhsValue = rhs._blocks[0]; + ulong carry = 0; + + for (int i = quoLength - 1; i >= 0; i--) + { + ulong value = (carry << 32) | lhs._blocks[i]; + ulong digit = MathEx.DivRem(value, rhsValue, out carry); + + if ((digit == 0) && (i == (quoLength - 1))) + { + quoLength--; + } + else + { + quo._blocks[i] = (uint)(digit); + } + } + + quo._length = quoLength; + SetUInt32(out rem, (uint)(carry)); + + return; + } + else if (rhsLength > lhsLength) + { + // Handle the case where we have no quotient + SetZero(out quo); + SetValue(out rem, ref lhs); + return; + } + else + { + int quoLength = lhsLength - rhsLength + 1; + SetValue(out rem, ref lhs); + int remLength = lhsLength; + + // Executes the "grammar-school" algorithm for computing q = a / b. + // Before calculating q_i, we get more bits into the highest bit + // block of the divisor. Thus, guessing digits of the quotient + // will be more precise. Additionally we'll get r = a % b. + + uint divHi = rhs._blocks[rhsLength - 1]; + uint divLo = rhs._blocks[rhsLength - 2]; + + // We measure the leading zeros of the divisor + int shiftLeft = BitOperations.LeadingZeroCount(divHi); + int shiftRight = 32 - shiftLeft; + + // And, we make sure the most significant bit is set + if (shiftLeft > 0) + { + divHi = (divHi << shiftLeft) | (divLo >> shiftRight); + divLo <<= shiftLeft; + + if (rhsLength > 2) + { + divLo |= (rhs._blocks[rhsLength - 3] >> shiftRight); + } + } + + // Then, we divide all of the bits as we would do it using + // pen and paper: guessing the next digit, subtracting, ... + for (int i = lhsLength; i >= rhsLength; i--) + { + int n = i - rhsLength; + uint t = i < lhsLength ? rem._blocks[i] : 0; + + ulong valHi = ((ulong)(t) << 32) | rem._blocks[i - 1]; + uint valLo = i > 1 ? rem._blocks[i - 2] : 0; + + // We shifted the divisor, we shift the dividend too + if (shiftLeft > 0) + { + valHi = (valHi << shiftLeft) | (valLo >> shiftRight); + valLo <<= shiftLeft; + + if (i > 2) + { + valLo |= (rem._blocks[i - 3] >> shiftRight); + } + } + + // First guess for the current digit of the quotient, + // which naturally must have only 32 bits... + ulong digit = valHi / divHi; + + if (digit > uint.MaxValue) + { + digit = uint.MaxValue; + } + + // Our first guess may be a little bit to big + while (DivideGuessTooBig(digit, valHi, valLo, divHi, divLo)) + { + digit--; + } + + if (digit > 0) + { + // Now it's time to subtract our current quotient + uint carry = SubtractDivisor(ref rem, n, ref rhs, digit); + + if (carry != t) + { + Debug.Assert(carry == t + 1); + + // Our guess was still exactly one too high + carry = AddDivisor(ref rem, n, ref rhs); + digit--; + + Debug.Assert(carry == 1); + } + } + + // We have the digit! + if (quoLength != 0) + { + if ((digit == 0) && (n == (quoLength - 1))) + { + quoLength--; + } + else + { + quo._blocks[n] = (uint)(digit); + } + } + + if (i < remLength) + { + remLength--; + } + } + + quo._length = quoLength; + + // We need to check for the case where remainder is zero + + for (int i = remLength - 1; i >= 0; i--) + { + if (rem._blocks[i] == 0) + { + remLength--; + } + } + + rem._length = remLength; + } + } + + public static uint HeuristicDivide(ref BigInteger dividend, ref BigInteger divisor) + { + int divisorLength = divisor._length; + + if (dividend._length < divisorLength) + { + return 0; + } + + // This is an estimated quotient. Its error should be less than 2. + // Reference inequality: + // a/b - floor(floor(a)/(floor(b) + 1)) < 2 + int lastIndex = (divisorLength - 1); + uint quotient = dividend._blocks[lastIndex] / (divisor._blocks[lastIndex] + 1); + + if (quotient != 0) + { + // Now we use our estimated quotient to update each block of dividend. + // dividend = dividend - divisor * quotient + int index = 0; + + ulong borrow = 0; + ulong carry = 0; + + do + { + ulong product = ((ulong)(divisor._blocks[index]) * quotient) + carry; + carry = product >> 32; + + ulong difference = (ulong)(dividend._blocks[index]) - (uint)(product) - borrow; + borrow = (difference >> 32) & 1; + + dividend._blocks[index] = (uint)(difference); + + index++; + } + while (index < divisorLength); + + // Remove all leading zero blocks from dividend + while ((divisorLength > 0) && (dividend._blocks[divisorLength - 1] == 0)) + { + divisorLength--; + } + + dividend._length = divisorLength; + } + + // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct, + // we increment the quotient and subtract one more divisor from the dividend (Because we guaranteed the error range). + if (Compare(ref dividend, ref divisor) >= 0) + { + quotient++; + + // dividend = dividend - divisor + int index = 0; + ulong borrow = 0; + + do + { + ulong difference = (ulong)(dividend._blocks[index]) - divisor._blocks[index] - borrow; + borrow = (difference >> 32) & 1; + + dividend._blocks[index] = (uint)(difference); + + index++; + } + while (index < divisorLength); + + // Remove all leading zero blocks from dividend + while ((divisorLength > 0) && (dividend._blocks[divisorLength - 1] == 0)) + { + divisorLength--; + } + + dividend._length = divisorLength; + } + + return quotient; + } + + public static void Multiply(ref BigInteger lhs, uint value, out BigInteger result) + { + if (lhs.IsZero() || (value == 1)) + { + SetValue(out result, ref lhs); + return; + } + + if (value == 0) + { + SetZero(out result); + return; + } + + int lhsLength = lhs._length; + int index = 0; + uint carry = 0; + + while (index < lhsLength) + { + ulong product = ((ulong)(lhs._blocks[index]) * value) + carry; + result._blocks[index] = (uint)(product); + carry = (uint)(product >> 32); + + index++; + } + + if (carry != 0) + { + Debug.Assert(unchecked((uint)(lhsLength)) + 1 <= MaxBlockCount); + result._blocks[index] = carry; + result._length = (lhsLength + 1); + } + else + { + result._length = lhsLength; + } + } + + public static void Multiply(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result) + { + if (lhs.IsZero() || rhs.IsOne()) + { + SetValue(out result, ref lhs); + return; + } + + if (rhs.IsZero()) + { + SetZero(out result); + return; + } + + ref readonly BigInteger large = ref lhs; + int largeLength = lhs._length; + + ref readonly BigInteger small = ref rhs; + int smallLength = rhs._length; + + if (largeLength < smallLength) + { + large = ref rhs; + largeLength = rhs._length; + + small = ref lhs; + smallLength = lhs._length; + } + + int maxResultLength = smallLength + largeLength; + Debug.Assert(unchecked((uint)(maxResultLength)) <= MaxBlockCount); + + // Zero out result internal blocks. + result._length = maxResultLength; + BufferEx.ZeroMemory((byte*)result.GetBlocksPointer(), (uint)maxResultLength * sizeof(uint)); + + int smallIndex = 0; + int resultStartIndex = 0; + + while (smallIndex < smallLength) + { + // Multiply each block of large BigNum. + if (small._blocks[smallIndex] != 0) + { + int largeIndex = 0; + int resultIndex = resultStartIndex; + + ulong carry = 0; + + do + { + ulong product = result._blocks[resultIndex] + ((ulong)(small._blocks[smallIndex]) * large._blocks[largeIndex]) + carry; + carry = product >> 32; + result._blocks[resultIndex] = (uint)(product); + + resultIndex++; + largeIndex++; + } + while (largeIndex < largeLength); + + result._blocks[resultIndex] = (uint)(carry); + } + + smallIndex++; + resultStartIndex++; + } + + if ((maxResultLength > 0) && (result._blocks[maxResultLength - 1] == 0)) + { + result._length--; + } + } + + public static void Pow2(uint exponent, out BigInteger result) + { + uint blocksToShift = DivRem32(exponent, out uint remainingBitsToShift); + result._length = (int)blocksToShift + 1; + Debug.Assert(unchecked((uint)result._length) <= MaxBlockCount); + if (blocksToShift > 0) + { + BufferEx.ZeroMemory((byte*)result.GetBlocksPointer(), blocksToShift * sizeof(uint)); + } + result._blocks[blocksToShift] = 1U << (int)(remainingBitsToShift); + } + + public static void Pow10(uint exponent, out BigInteger result) + { + // We leverage two arrays - s_Pow10UInt32Table and s_Pow10BigNumTable to speed up the Pow10 calculation. + // + // s_Pow10UInt32Table stores the results of 10^0 to 10^7. + // s_Pow10BigNumTable stores the results of 10^8, 10^16, 10^32, 10^64, 10^128, 10^256, and 10^512 + // + // For example, let's say exp = 0b111111. We can split the exp to two parts, one is small exp, + // which 10^smallExp can be represented as uint, another part is 10^bigExp, which must be represented as BigNum. + // So the result should be 10^smallExp * 10^bigExp. + // + // Calculating 10^smallExp is simple, we just lookup the 10^smallExp from s_Pow10UInt32Table. + // But here's a bad news: although uint can represent 10^9, exp 9's binary representation is 1001. + // That means 10^(1011), 10^(1101), 10^(1111) all cannot be stored as uint, we cannot easily say something like: + // "Any bits <= 3 is small exp, any bits > 3 is big exp". So instead of involving 10^8, 10^9 to s_Pow10UInt32Table, + // consider 10^8 and 10^9 as a bigNum, so they fall into s_Pow10BigNumTable. Now we can have a simple rule: + // "Any bits <= 3 is small exp, any bits > 3 is big exp". + // + // For 0b111111, we first calculate 10^(smallExp), which is 10^(7), now we can shift right 3 bits, prepare to calculate the bigExp part, + // the exp now becomes 0b000111. + // + // Apparently the lowest bit of bigExp should represent 10^8 because we have already shifted 3 bits for smallExp, so s_Pow10BigNumTable[0] = 10^8. + // Now let's shift exp right 1 bit, the lowest bit should represent 10^(8 * 2) = 10^16, and so on... + // + // That's why we just need the values of s_Pow10BigNumTable be power of 2. + // + // More details of this implementation can be found at: https://github.com/dotnet/coreclr/pull/12894#discussion_r128890596 + + // Validate that `s_Pow10BigNumTable` has exactly enough trailing elements to fill a BigInteger (which contains MaxBlockCount + 1 elements) + // We validate here, since this is the only current consumer of the array + Debug.Assert((s_Pow10BigNumTableIndices[s_Pow10BigNumTableIndices.Length - 1] + MaxBlockCount + 2) == s_Pow10BigNumTable.Length); + + SetUInt32(out BigInteger temp1, s_Pow10UInt32Table[exponent & 0x7]); + ref BigInteger lhs = ref temp1; + + SetZero(out BigInteger temp2); + ref BigInteger product = ref temp2; + + exponent >>= 3; + uint index = 0; + + while (exponent != 0) + { + // If the current bit is set, multiply it with the corresponding power of 10 + if ((exponent & 1) != 0) + { + // Multiply into the next temporary + fixed (uint* pBigNumEntry = &s_Pow10BigNumTable[s_Pow10BigNumTableIndices[index]]) + { + ref BigInteger rhs = ref *(BigInteger*)(pBigNumEntry); + Multiply(ref lhs, ref rhs, out product); + } + + // Swap to the next temporary + ref BigInteger temp = ref product; + product = ref lhs; + lhs = ref temp; + } + + // Advance to the next bit + ++index; + exponent >>= 1; + } + + SetValue(out result, ref lhs); + } + + private static uint AddDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs) + { + int lhsLength = lhs._length; + int rhsLength = rhs._length; + + Debug.Assert(lhsLength >= 0); + Debug.Assert(rhsLength >= 0); + Debug.Assert(lhsLength >= rhsLength); + + // Repairs the dividend, if the last subtract was too much + + ulong carry = 0UL; + + for (int i = 0; i < rhsLength; i++) + { + ref uint lhsValue = ref lhs._blocks[lhsStartIndex + i]; + + ulong digit = lhsValue + carry + rhs._blocks[i]; + lhsValue = unchecked((uint)digit); + carry = digit >> 32; + } + + return (uint)(carry); + } + + private static bool DivideGuessTooBig(ulong q, ulong valHi, uint valLo, uint divHi, uint divLo) + { + Debug.Assert(q <= 0xFFFFFFFF); + + // We multiply the two most significant limbs of the divisor + // with the current guess for the quotient. If those are bigger + // than the three most significant limbs of the current dividend + // we return true, which means the current guess is still too big. + + ulong chkHi = divHi * q; + ulong chkLo = divLo * q; + + chkHi += (chkLo >> 32); + chkLo &= uint.MaxValue; + + if (chkHi < valHi) + return false; + + if (chkHi > valHi) + return true; + + if (chkLo < valLo) + return false; + + if (chkLo > valLo) + return true; + + return false; + } + + private static uint SubtractDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs, ulong q) + { + int lhsLength = lhs._length - lhsStartIndex; + int rhsLength = rhs._length; + + Debug.Assert(lhsLength >= 0); + Debug.Assert(rhsLength >= 0); + Debug.Assert(lhsLength >= rhsLength); + Debug.Assert(q <= uint.MaxValue); + + // Combines a subtract and a multiply operation, which is naturally + // more efficient than multiplying and then subtracting... + + ulong carry = 0; + + for (int i = 0; i < rhsLength; i++) + { + carry += rhs._blocks[i] * q; + uint digit = unchecked((uint)carry); + carry >>= 32; + + ref uint lhsValue = ref lhs._blocks[lhsStartIndex + i]; + + if (lhsValue < digit) + { + carry++; + } + + lhsValue = unchecked(lhsValue - digit); + } + + return (uint)(carry); + } + + public void Add(uint value) + { + int length = _length; + if (length == 0) + { + SetUInt32(out this, value); + return; + } + + _blocks[0] += value; + if (_blocks[0] >= value) + { + // No carry + return; + } + + for (int index = 1; index < length; index++) + { + _blocks[index]++; + if (_blocks[index] > 0) + { + // No carry + return; + } + } + + Debug.Assert(unchecked((uint)(length)) + 1 <= MaxBlockCount); + _blocks[length] = 1; + _length = length + 1; + } + + public uint GetBlock(uint index) + { + Debug.Assert(index < _length); + return _blocks[index]; + } + + public int GetLength() + { + return _length; + } + + public bool IsOne() + { + return (_length == 1) + && (_blocks[0] == 1); + } + + public bool IsZero() + { + return _length == 0; + } + + public void Multiply(uint value) + { + Multiply(ref this, value, out this); + } + + public void Multiply(ref BigInteger value) + { + SetValue(out BigInteger temp, ref this); + Multiply(ref temp, ref value, out this); + } + + public void Multiply10() + { + if (IsZero()) + { + return; + } + + int index = 0; + int length = _length; + ulong carry = 0; + + while (index < length) + { + ulong block = (ulong)(_blocks[index]); + ulong product = (block << 3) + (block << 1) + carry; + carry = product >> 32; + _blocks[index] = (uint)(product); + + index++; + } + + if (carry != 0) + { + Debug.Assert(unchecked((uint)(_length)) + 1 <= MaxBlockCount); + _blocks[index] = (uint)carry; + _length++; + } + } + + public void MultiplyPow10(uint exponent) + { + if (IsZero()) + { + return; + } + + Pow10(exponent, out BigInteger poweredValue); + + if (poweredValue._length == 1) + { + Multiply(poweredValue._blocks[0]); + } + else + { + Multiply(ref poweredValue); + } + } + + public static void SetUInt32(out BigInteger result, uint value) + { + if (value == 0) + { + SetZero(out result); + } + else + { + result._blocks[0] = value; + result._length = 1; + } + } + + public static void SetUInt64(out BigInteger result, ulong value) + { + if (value <= uint.MaxValue) + { + SetUInt32(out result, (uint)(value)); + } + else + { + result._blocks[0] = (uint)(value); + result._blocks[1] = (uint)(value >> 32); + + result._length = 2; + } + } + + public static void SetValue(out BigInteger result, ref BigInteger value) + { + int rhsLength = value._length; + result._length = rhsLength; + BufferEx.Memcpy((byte*)result.GetBlocksPointer(), (byte*)value.GetBlocksPointer(), rhsLength * sizeof(uint)); + } + + public static void SetZero(out BigInteger result) + { + result._length = 0; + } + + public void ShiftLeft(uint shift) + { + // Process blocks high to low so that we can safely process in place + int length = _length; + + if ((length == 0) || (shift == 0)) + { + return; + } + + uint blocksToShift = DivRem32(shift, out uint remainingBitsToShift); + + // Copy blocks from high to low + int readIndex = (length - 1); + int writeIndex = readIndex + (int)(blocksToShift); + + // Check if the shift is block aligned + if (remainingBitsToShift == 0) + { + Debug.Assert(writeIndex < MaxBlockCount); + + while (readIndex >= 0) + { + _blocks[writeIndex] = _blocks[readIndex]; + readIndex--; + writeIndex--; + } + + _length += (int)(blocksToShift); + + // Zero the remaining low blocks + BufferEx.ZeroMemory((byte*)GetBlocksPointer(), blocksToShift * sizeof(uint)); + } + else + { + // We need an extra block for the partial shift + writeIndex++; + Debug.Assert(writeIndex < MaxBlockCount); + + // Set the length to hold the shifted blocks + _length = writeIndex + 1; + + // Output the initial blocks + uint lowBitsShift = (32 - remainingBitsToShift); + uint highBits = 0; + uint block = _blocks[readIndex]; + uint lowBits = block >> (int)(lowBitsShift); + while (readIndex > 0) + { + _blocks[writeIndex] = highBits | lowBits; + highBits = block << (int)(remainingBitsToShift); + + --readIndex; + --writeIndex; + + block = _blocks[readIndex]; + lowBits = block >> (int)lowBitsShift; + } + + // Output the final blocks + _blocks[writeIndex] = highBits | lowBits; + _blocks[writeIndex - 1] = block << (int)(remainingBitsToShift); + + // Zero the remaining low blocks + BufferEx.ZeroMemory((byte*)GetBlocksPointer(), blocksToShift * sizeof(uint)); + + // Check if the terminating block has no set bits + if (_blocks[_length - 1] == 0) + { + _length--; + } + } + } + + public ulong ToUInt64() + { + if (_length > 1) + { + return ((ulong)(_blocks[1]) << 32) + _blocks[0]; + } + + if (_length > 0) + { + return _blocks[0]; + } + + return 0; + } + + private uint* GetBlocksPointer() + { + // This is safe to do since we are a ref struct + return (uint*)(Unsafe.AsPointer(ref _blocks[0])); + } + + private static uint DivRem32(uint value, out uint remainder) + { + remainder = value & 31; + return value >> 5; + } + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.DiyFp.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.DiyFp.cs new file mode 100644 index 00000000..562dd9a1 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.DiyFp.cs @@ -0,0 +1,157 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Numerics; + +namespace System +{ + internal static partial class Number + { + // This is a port of the `DiyFp` implementation here: https://github.com/google/double-conversion/blob/a711666ddd063eb1e4b181a6cb981d39a1fc8bac/double-conversion/diy-fp.h + // The backing structure and how it is used is described in more detail here: http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf + + // This "Do It Yourself Floating Point" class implements a floating-point number with a ulong significand and an int exponent. + // Normalized DiyFp numbers will have the most significant bit of the significand set. + // Multiplication and Subtraction do not normalize their results. + // DiyFp are not designed to contain special doubles (NaN and Infinity). + internal readonly ref struct DiyFp + { + public const int DoubleImplicitBitIndex = 52; + public const int SingleImplicitBitIndex = 23; + + public const int SignificandSize = 64; + + public readonly ulong f; + public readonly int e; + + // Computes the two boundaries of value. + // + // The bigger boundary (mPlus) is normalized. + // The lower boundary has the same exponent as mPlus. + // + // Precondition: + // The value encoded by value must be greater than 0. + public static DiyFp CreateAndGetBoundaries(double value, out DiyFp mMinus, out DiyFp mPlus) + { + var result = new DiyFp(value); + result.GetBoundaries(DoubleImplicitBitIndex, out mMinus, out mPlus); + return result; + } + + // Computes the two boundaries of value. + // + // The bigger boundary (mPlus) is normalized. + // The lower boundary has the same exponent as mPlus. + // + // Precondition: + // The value encoded by value must be greater than 0. + public static DiyFp CreateAndGetBoundaries(float value, out DiyFp mMinus, out DiyFp mPlus) + { + var result = new DiyFp(value); + result.GetBoundaries(SingleImplicitBitIndex, out mMinus, out mPlus); + return result; + } + + public DiyFp(double value) + { + //Debug.Assert(double.IsFinite(value)); + Debug.Assert(value > 0.0); + f = ExtractFractionAndBiasedExponent(value, out e); + } + + public DiyFp(float value) + { + //Debug.Assert(float.IsFinite(value)); + Debug.Assert(value > 0.0f); + f = ExtractFractionAndBiasedExponent(value, out e); + } + + public DiyFp(ulong f, int e) + { + this.f = f; + this.e = e; + } + + public DiyFp Multiply(in DiyFp other) + { + // Simply "emulates" a 128-bit multiplication + // + // However: the resulting number only contains 64-bits. The least + // signficant 64-bits are only used for rounding the most significant + // 64-bits. + + uint a = (uint)(f >> 32); + uint b = (uint)(f); + + uint c = (uint)(other.f >> 32); + uint d = (uint)(other.f); + + ulong ac = ((ulong)(a) * c); + ulong bc = ((ulong)(b) * c); + ulong ad = ((ulong)(a) * d); + ulong bd = ((ulong)(b) * d); + + ulong tmp = (bd >> 32) + (uint)(ad) + (uint)(bc); + + // By adding (1UL << 31) to tmp, we round the final result. + // Halfway cases will be rounded up. + + tmp += (1U << 31); + + return new DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + other.e + SignificandSize); + } + + public DiyFp Normalize() + { + // This method is mainly called for normalizing boundaries. + // + // We deviate from the reference implementation by just using + // our LeadingZeroCount function so that we only need to shift + // and subtract once. + + Debug.Assert(f != 0); + int lzcnt = BitOperations.LeadingZeroCount(f); + return new DiyFp(f << lzcnt, e - lzcnt); + } + + // The exponents of both numbers must be the same. + // The significand of 'this' must be bigger than the significand of 'other'. + // The result will not be normalized. + public DiyFp Subtract(in DiyFp other) + { + Debug.Assert(e == other.e); + Debug.Assert(f >= other.f); + return new DiyFp(f - other.f, e); + } + + private void GetBoundaries(int implicitBitIndex, out DiyFp mMinus, out DiyFp mPlus) + { + mPlus = new DiyFp((f << 1) + 1, e - 1).Normalize(); + + // The boundary is closer if the sigificand is of the form: + // f == 2^p-1 + // + // Think of v = 1000e10 and v- = 9999e9 + // Then the boundary == (v - v-) / 2 is not just at a distance of 1e9 but at a distance of 1e8. + // The only exception is for the smallest normal, where the largest denormal is at the same distance as its successor. + // + // Note: denormals have the same exponent as the smallest normals. + + // We deviate from the reference implementation by just checking if the significand has only the implicit bit set. + // In this scenario, we know that all the explicit bits are 0 and that the unbiased exponent is non-zero. + if (f == (1UL << implicitBitIndex)) + { + mMinus = new DiyFp((f << 2) - 1, e - 2); + } + else + { + mMinus = new DiyFp((f << 1) - 1, e - 1); + } + + mMinus = new DiyFp(mMinus.f << (mMinus.e - mPlus.e), mPlus.e); + } + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Dragon4.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Dragon4.cs new file mode 100644 index 00000000..4831987f --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Dragon4.cs @@ -0,0 +1,525 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System +{ + // This is a port of the `Dragon4` implementation here: http://www.ryanjuckett.com/programming/printing-floating-point-numbers/part-2/ + // The backing algorithm and the proofs behind it are described in more detail here: https://www.cs.indiana.edu/~dyb/pubs/FP-Printing-PLDI96.pdf + internal static partial class Number + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe bool IsNegative(double d) + { + return BitConverter.DoubleToInt64Bits(d) < 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe bool IsNegativeInfinity(float f) + { + return f == float.NegativeInfinity; + } + + public static void Dragon4Double(double value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number) + { + double v = IsNegative(value) ? -value : value; + + Debug.Assert(v > 0); + // Debug.Assert(double.IsFinite(v)); + + ulong mantissa = ExtractFractionAndBiasedExponent(value, out int exponent); + + uint mantissaHighBitIdx; + bool hasUnequalMargins = false; + + if ((mantissa >> DiyFp.DoubleImplicitBitIndex) != 0) + { + mantissaHighBitIdx = DiyFp.DoubleImplicitBitIndex; + hasUnequalMargins = (mantissa == (1UL << DiyFp.DoubleImplicitBitIndex)); + } + else + { + Debug.Assert(mantissa != 0); + mantissaHighBitIdx = (uint)BitOperations.Log2(mantissa); + } + + int length = (int)(Dragon4(mantissa, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out int decimalExponent)); + + number.Scale = decimalExponent + 1; + number.Digits[length] = (byte)('\0'); + number.DigitsCount = length; + } + + public static unsafe void Dragon4Single(float value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number) + { + float v = IsNegative(value) ? -value : value; + + Debug.Assert(v > 0); + // Debug.Assert(float.IsFinite(v)); + + uint mantissa = ExtractFractionAndBiasedExponent(value, out int exponent); + + uint mantissaHighBitIdx; + bool hasUnequalMargins = false; + + if ((mantissa >> DiyFp.SingleImplicitBitIndex) != 0) + { + mantissaHighBitIdx = DiyFp.SingleImplicitBitIndex; + hasUnequalMargins = (mantissa == (1U << DiyFp.SingleImplicitBitIndex)); + } + else + { + Debug.Assert(mantissa != 0); + mantissaHighBitIdx = (uint)BitOperations.Log2(mantissa); + } + + int length = (int)(Dragon4(mantissa, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out int decimalExponent)); + + number.Scale = decimalExponent + 1; + number.Digits[length] = (byte)('\0'); + number.DigitsCount = length; + } + + // This is an implementation of the Dragon4 algorithm to convert a binary number in floating-point format to a decimal number in string format. + // The function returns the number of digits written to the output buffer and the output is not NUL terminated. + // + // The floating point input value is (mantissa * 2^exponent). + // + // See the following papers for more information on the algorithm: + // "How to Print Floating-Point Numbers Accurately" + // Steele and White + // http://kurtstephens.com/files/p372-steele.pdf + // "Printing Floating-Point Numbers Quickly and Accurately" + // Burger and Dybvig + // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf + private static unsafe uint Dragon4(ulong mantissa, int exponent, uint mantissaHighBitIdx, bool hasUnequalMargins, int cutoffNumber, bool isSignificantDigits, Span buffer, out int decimalExponent) + { + int curDigit = 0; + + Debug.Assert(buffer.Length > 0); + + // We deviate from the original algorithm and just assert that the mantissa + // is not zero. Comparing to zero is fine since the caller should have set + // the implicit bit of the mantissa, meaning it would only ever be zero if + // the extracted exponent was also zero. And the assertion is fine since we + // require that the DoubleToNumber handle zero itself. + Debug.Assert(mantissa != 0); + + // Compute the initial state in integral form such that + // value = scaledValue / scale + // marginLow = scaledMarginLow / scale + + BigInteger scale; // positive scale applied to value and margin such that they can be represented as whole numbers + BigInteger scaledValue; // scale * mantissa + BigInteger scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its immediate lower value) + + // For normalized IEEE floating-point values, each time the exponent is incremented the margin also doubles. + // That creates a subset of transition numbers where the high margin is twice the size of the low margin. + BigInteger* pScaledMarginHigh; + BigInteger optionalMarginHigh; + + if (hasUnequalMargins) + { + if (exponent > 0) // We have no fractional component + { + // 1) Expand the input value by multiplying out the mantissa and exponent. + // This represents the input value in its whole number representation. + // 2) Apply an additional scale of 2 such that later comparisons against the margin values are simplified. + // 3) Set the margin value to the loweset mantissa bit's scale. + + // scaledValue = 2 * 2 * mantissa * 2^exponent + BigInteger.SetUInt64(out scaledValue, 4 * mantissa); + scaledValue.ShiftLeft((uint)(exponent)); + + // scale = 2 * 2 * 1 + BigInteger.SetUInt32(out scale, 4); + + // scaledMarginLow = 2 * 2^(exponent - 1) + BigInteger.Pow2((uint)(exponent), out scaledMarginLow); + + // scaledMarginHigh = 2 * 2 * 2^(exponent + 1) + BigInteger.Pow2((uint)(exponent + 1), out optionalMarginHigh); + } + else // We have a fractional exponent + { + // In order to track the mantissa data as an integer, we store it as is with a large scale + + // scaledValue = 2 * 2 * mantissa + BigInteger.SetUInt64(out scaledValue, 4 * mantissa); + + // scale = 2 * 2 * 2^(-exponent) + BigInteger.Pow2((uint)(-exponent + 2), out scale); + + // scaledMarginLow = 2 * 2^(-1) + BigInteger.SetUInt32(out scaledMarginLow, 1); + + // scaledMarginHigh = 2 * 2 * 2^(-1) + BigInteger.SetUInt32(out optionalMarginHigh, 2); + } + + // The high and low margins are different + pScaledMarginHigh = &optionalMarginHigh; + } + else + { + if (exponent > 0) // We have no fractional component + { + // 1) Expand the input value by multiplying out the mantissa and exponent. + // This represents the input value in its whole number representation. + // 2) Apply an additional scale of 2 such that later comparisons against the margin values are simplified. + // 3) Set the margin value to the lowest mantissa bit's scale. + + // scaledValue = 2 * mantissa*2^exponent + BigInteger.SetUInt64(out scaledValue, 2 * mantissa); + scaledValue.ShiftLeft((uint)(exponent)); + + // scale = 2 * 1 + BigInteger.SetUInt32(out scale, 2); + + // scaledMarginLow = 2 * 2^(exponent-1) + BigInteger.Pow2((uint)(exponent), out scaledMarginLow); + } + else // We have a fractional exponent + { + // In order to track the mantissa data as an integer, we store it as is with a large scale + + // scaledValue = 2 * mantissa + BigInteger.SetUInt64(out scaledValue, 2 * mantissa); + + // scale = 2 * 2^(-exponent) + BigInteger.Pow2((uint)(-exponent + 1), out scale); + + // scaledMarginLow = 2 * 2^(-1) + BigInteger.SetUInt32(out scaledMarginLow, 1); + } + + // The high and low margins are equal + pScaledMarginHigh = &scaledMarginLow; + } + + // Compute an estimate for digitExponent that will be correct or undershoot by one. + // + // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately" by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf + // + // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate because that lets us take a faster branch in the code. + // 0.69 is chosen because 0.69 + log10(2) is less than one by a reasonable epsilon that will account for any floating point error. + // + // We want to set digitExponent to floor(log10(v)) + 1 + // v = mantissa * 2^exponent + // log2(v) = log2(mantissa) + exponent; + // log10(v) = log2(v) * log10(2) + // floor(log2(v)) = mantissaHighBitIdx + exponent; + // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v) + // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2) + // floor(log10(v)) < ceil((mantissaHighBitIdx + exponent) * log10(2)) <= floor(log10(v)) + 1 + const double Log10V2 = 0.30102999566398119521373889472449; + int digitExponent = (int)(Math.Ceiling(((int)(mantissaHighBitIdx) + exponent) * Log10V2 - 0.69)); + + // Divide value by 10^digitExponent. + if (digitExponent > 0) + { + // The exponent is positive creating a division so we multiply up the scale. + scale.MultiplyPow10((uint)(digitExponent)); + } + else if (digitExponent < 0) + { + // The exponent is negative creating a multiplication so we multiply up the scaledValue, scaledMarginLow and scaledMarginHigh. + + BigInteger.Pow10((uint)(-digitExponent), out BigInteger pow10); + + scaledValue.Multiply(ref pow10); + scaledMarginLow.Multiply(ref pow10); + + if (pScaledMarginHigh != &scaledMarginLow) + { + BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); + } + } + + bool isEven = (mantissa % 2) == 0; + bool estimateTooLow = false; + + if (cutoffNumber == -1) + { + // When printing the shortest possible string, we want to + // take IEEE unbiased rounding into account so we can return + // shorter strings for various edge case values like 1.23E+22 + + BigInteger.Add(ref scaledValue, ref *pScaledMarginHigh, out BigInteger scaledValueHigh); + int cmpHigh = BigInteger.Compare(ref scaledValueHigh, ref scale); + estimateTooLow = isEven ? (cmpHigh >= 0) : (cmpHigh > 0); + } + else + { + estimateTooLow = BigInteger.Compare(ref scaledValue, ref scale) >= 0; + } + + // Was our estimate for digitExponent was too low? + if (estimateTooLow) + { + // The exponent estimate was incorrect. + // Increment the exponent and don't perform the premultiply needed for the first loop iteration. + digitExponent++; + } + else + { + // The exponent estimate was correct. + // Multiply larger by the output base to prepare for the first loop iteration. + scaledValue.Multiply10(); + scaledMarginLow.Multiply10(); + + if (pScaledMarginHigh != &scaledMarginLow) + { + BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); + } + } + + // Compute the cutoff exponent (the exponent of the final digit to print). + // Default to the maximum size of the output buffer. + int cutoffExponent = digitExponent - buffer.Length; + + if (cutoffNumber != -1) + { + int desiredCutoffExponent = 0; + + if (isSignificantDigits) + { + // We asked for a specific number of significant digits. + Debug.Assert(cutoffNumber > 0); + desiredCutoffExponent = digitExponent - cutoffNumber; + } + else + { + // We asked for a specific number of fractional digits. + Debug.Assert(cutoffNumber >= 0); + desiredCutoffExponent = -cutoffNumber; + } + + if (desiredCutoffExponent > cutoffExponent) + { + // Only select the new cutoffExponent if it won't overflow the destination buffer. + cutoffExponent = desiredCutoffExponent; + } + } + + // Output the exponent of the first digit we will print + decimalExponent = --digitExponent; + + // In preparation for calling BigInteger.HeuristicDivie(), we need to scale up our values such that the highest block of the denominator is greater than or equal to 8. + // We also need to guarantee that the numerator can never have a length greater than the denominator after each loop iteration. + // This requires the highest block of the denominator to be less than or equal to 429496729 which is the highest number that can be multiplied by 10 without overflowing to a new block. + + Debug.Assert(scale.GetLength() > 0); + uint hiBlock = scale.GetBlock((uint)(scale.GetLength() - 1)); + + if ((hiBlock < 8) || (hiBlock > 429496729)) + { + // Perform a bit shift on all values to get the highest block of the denominator into the range [8,429496729]. + // We are more likely to make accurate quotient estimations in BigInteger.HeuristicDivide() with higher denominator values so we shift the denominator to place the highest bit at index 27 of the highest block. + // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. + // This means that all values with a highest bit at index 27 are within range. + Debug.Assert(hiBlock != 0); + uint hiBlockLog2 = (uint)BitOperations.Log2(hiBlock); + Debug.Assert((hiBlockLog2 < 3) || (hiBlockLog2 > 27)); + uint shift = (32 + 27 - hiBlockLog2) % 32; + + scale.ShiftLeft(shift); + scaledValue.ShiftLeft(shift); + scaledMarginLow.ShiftLeft(shift); + + if (pScaledMarginHigh != &scaledMarginLow) + { + BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); + } + } + + // These values are used to inspect why the print loop terminated so we can properly round the final digit. + bool low; // did the value get within marginLow distance from zero + bool high; // did the value get within marginHigh distance from one + uint outputDigit; // current digit being output + + if (cutoffNumber == -1) + { + Debug.Assert(isSignificantDigits); + Debug.Assert(digitExponent >= cutoffExponent); + + // For the unique cutoff mode, we will try to print until we have reached a level of precision that uniquely distinguishes this value from its neighbors. + // If we run out of space in the output buffer, we terminate early. + + while (true) + { + // divide out the scale to extract the digit + outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); + Debug.Assert(outputDigit < 10); + + // update the high end of the value + BigInteger.Add(ref scaledValue, ref *pScaledMarginHigh, out BigInteger scaledValueHigh); + + // stop looping if we are far enough away from our neighboring values or if we have reached the cutoff digit + int cmpLow = BigInteger.Compare(ref scaledValue, ref scaledMarginLow); + int cmpHigh = BigInteger.Compare(ref scaledValueHigh, ref scale); + + if (isEven) + { + low = (cmpLow <= 0); + high = (cmpHigh >= 0); + } + else + { + low = (cmpLow < 0); + high = (cmpHigh > 0); + } + + if (low || high || (digitExponent == cutoffExponent)) + { + break; + } + + // store the output digit + buffer[curDigit] = (byte)('0' + outputDigit); + curDigit++; + + // multiply larger by the output base + scaledValue.Multiply10(); + scaledMarginLow.Multiply10(); + + if (pScaledMarginHigh != &scaledMarginLow) + { + BigInteger.Multiply(ref scaledMarginLow, 2, out *pScaledMarginHigh); + } + + digitExponent--; + } + } + else if (digitExponent >= cutoffExponent) + { + Debug.Assert((cutoffNumber > 0) || ((cutoffNumber == 0) && !isSignificantDigits)); + + // For length based cutoff modes, we will try to print until we have exhausted all precision (i.e. all remaining digits are zeros) or until we reach the desired cutoff digit. + low = false; + high = false; + + while (true) + { + // divide out the scale to extract the digit + outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); + Debug.Assert(outputDigit < 10); + + if (scaledValue.IsZero() || (digitExponent <= cutoffExponent)) + { + break; + } + + // store the output digit + buffer[curDigit] = (byte)('0' + outputDigit); + curDigit++; + + // multiply larger by the output base + scaledValue.Multiply10(); + digitExponent--; + } + } + else + { + // In the scenario where the first significant digit is after the cutoff, we want to treat that + // first significant digit as the rounding digit. If the first significant would cause the next + // digit to round, we will increase the decimalExponent by one and set the previous digit to one. + // This ensures we correctly handle the case where the first significant digit is exactly one after + // the cutoff, it is a 4, and the subsequent digit would round that to 5 inducing a double rounding + // bug when NumberToString does its own rounding checks. However, if the first significant digit + // would not cause the next one to round, we preserve that digit as is. + + // divide out the scale to extract the digit + outputDigit = BigInteger.HeuristicDivide(ref scaledValue, ref scale); + Debug.Assert((0 < outputDigit) && (outputDigit < 10)); + + if ((outputDigit > 5) || ((outputDigit == 5) && !scaledValue.IsZero())) + { + decimalExponent++; + outputDigit = 1; + } + + buffer[curDigit] = (byte)('0' + outputDigit); + curDigit++; + + // return the number of digits output + return (uint)curDigit; + } + + // round off the final digit + // default to rounding down if value got too close to 0 + bool roundDown = low; + + if (low == high) // is it legal to round up and down + { + // round to the closest digit by comparing value with 0.5. + // + // To do this we need to convert the inequality to large integer values. + // compare(value, 0.5) + // compare(scale * value, scale * 0.5) + // compare(2 * scale * value, scale) + scaledValue.ShiftLeft(1); // Multiply by 2 + int compare = BigInteger.Compare(ref scaledValue, ref scale); + roundDown = compare < 0; + + // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules) + if (compare == 0) + { + roundDown = (outputDigit & 1) == 0; + } + } + + // print the rounded digit + if (roundDown) + { + buffer[curDigit] = (byte)('0' + outputDigit); + curDigit++; + } + else if (outputDigit == 9) // handle rounding up + { + // find the first non-nine prior digit + while (true) + { + // if we are at the first digit + if (curDigit == 0) + { + // output 1 at the next highest exponent + + buffer[curDigit] = (byte)('1'); + curDigit++; + decimalExponent++; + + break; + } + + curDigit--; + + if (buffer[curDigit] != '9') + { + // increment the digit + + buffer[curDigit]++; + curDigit++; + + break; + } + } + } + else + { + // values in the range [0,8] can perform a simple round up + buffer[curDigit] = (byte)('0' + outputDigit + 1); + curDigit++; + } + + // return the number of digits output + uint outputLen = (uint)curDigit; + Debug.Assert(outputLen <= buffer.Length); + return outputLen; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Formatting.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Formatting.cs new file mode 100644 index 00000000..eb2d402f --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Formatting.cs @@ -0,0 +1,2544 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Buffers.Text; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace System +{ + // The Format methods provided by the numeric classes convert + // the numeric value to a string using the format string given by the + // format parameter. If the format parameter is null or + // an empty string, the number is formatted as if the string "G" (general + // format) was specified. The info parameter specifies the + // NumberFormatInfo instance to use when formatting the number. If the + // info parameter is null or omitted, the numeric formatting information + // is obtained from the current culture. The NumberFormatInfo supplies + // such information as the characters to use for decimal and thousand + // separators, and the spelling and placement of currency symbols in monetary + // values. + // + // Format strings fall into two categories: Standard format strings and + // user-defined format strings. A format string consisting of a single + // alphabetic character (A-Z or a-z), optionally followed by a sequence of + // digits (0-9), is a standard format string. All other format strings are + // used-defined format strings. + // + // A standard format string takes the form Axx, where A is an + // alphabetic character called the format specifier and xx is a + // sequence of digits called the precision specifier. The format + // specifier controls the type of formatting applied to the number and the + // precision specifier controls the number of significant digits or decimal + // places of the formatting operation. The following table describes the + // supported standard formats. + // + // C c - Currency format. The number is + // converted to a string that represents a currency amount. The conversion is + // controlled by the currency format information of the NumberFormatInfo + // used to format the number. The precision specifier indicates the desired + // number of decimal places. If the precision specifier is omitted, the default + // currency precision given by the NumberFormatInfo is used. + // + // D d - Decimal format. This format is + // supported for integral types only. The number is converted to a string of + // decimal digits, prefixed by a minus sign if the number is negative. The + // precision specifier indicates the minimum number of digits desired in the + // resulting string. If required, the number will be left-padded with zeros to + // produce the number of digits given by the precision specifier. + // + // E e Engineering (scientific) format. + // The number is converted to a string of the form + // "-d.ddd...E+ddd" or "-d.ddd...e+ddd", where each + // 'd' indicates a digit (0-9). The string starts with a minus sign if the + // number is negative, and one digit always precedes the decimal point. The + // precision specifier indicates the desired number of digits after the decimal + // point. If the precision specifier is omitted, a default of 6 digits after + // the decimal point is used. The format specifier indicates whether to prefix + // the exponent with an 'E' or an 'e'. The exponent is always consists of a + // plus or minus sign and three digits. + // + // F f Fixed point format. The number is + // converted to a string of the form "-ddd.ddd....", where each + // 'd' indicates a digit (0-9). The string starts with a minus sign if the + // number is negative. The precision specifier indicates the desired number of + // decimal places. If the precision specifier is omitted, the default numeric + // precision given by the NumberFormatInfo is used. + // + // G g - General format. The number is + // converted to the shortest possible decimal representation using fixed point + // or scientific format. The precision specifier determines the number of + // significant digits in the resulting string. If the precision specifier is + // omitted, the number of significant digits is determined by the type of the + // number being converted (10 for int, 19 for long, 7 for + // float, 15 for double, 19 for Currency, and 29 for + // Decimal). Trailing zeros after the decimal point are removed, and the + // resulting string contains a decimal point only if required. The resulting + // string uses fixed point format if the exponent of the number is less than + // the number of significant digits and greater than or equal to -4. Otherwise, + // the resulting string uses scientific format, and the case of the format + // specifier controls whether the exponent is prefixed with an 'E' or an 'e'. + // + // N n Number format. The number is + // converted to a string of the form "-d,ddd,ddd.ddd....", where + // each 'd' indicates a digit (0-9). The string starts with a minus sign if the + // number is negative. Thousand separators are inserted between each group of + // three digits to the left of the decimal point. The precision specifier + // indicates the desired number of decimal places. If the precision specifier + // is omitted, the default numeric precision given by the + // NumberFormatInfo is used. + // + // X x - Hexadecimal format. This format is + // supported for integral types only. The number is converted to a string of + // hexadecimal digits. The format specifier indicates whether to use upper or + // lower case characters for the hexadecimal digits above 9 ('X' for 'ABCDEF', + // and 'x' for 'abcdef'). The precision specifier indicates the minimum number + // of digits desired in the resulting string. If required, the number will be + // left-padded with zeros to produce the number of digits given by the + // precision specifier. + // + // Some examples of standard format strings and their results are shown in the + // table below. (The examples all assume a default NumberFormatInfo.) + // + // Value Format Result + // 12345.6789 C $12,345.68 + // -12345.6789 C ($12,345.68) + // 12345 D 12345 + // 12345 D8 00012345 + // 12345.6789 E 1.234568E+004 + // 12345.6789 E10 1.2345678900E+004 + // 12345.6789 e4 1.2346e+004 + // 12345.6789 F 12345.68 + // 12345.6789 F0 12346 + // 12345.6789 F6 12345.678900 + // 12345.6789 G 12345.6789 + // 12345.6789 G7 12345.68 + // 123456789 G7 1.234568E8 + // 12345.6789 N 12,345.68 + // 123456789 N4 123,456,789.0000 + // 0x2c45e x 2c45e + // 0x2c45e X 2C45E + // 0x2c45e X8 0002C45E + // + // Format strings that do not start with an alphabetic character, or that start + // with an alphabetic character followed by a non-digit, are called + // user-defined format strings. The following table describes the formatting + // characters that are supported in user defined format strings. + // + // + // 0 - Digit placeholder. If the value being + // formatted has a digit in the position where the '0' appears in the format + // string, then that digit is copied to the output string. Otherwise, a '0' is + // stored in that position in the output string. The position of the leftmost + // '0' before the decimal point and the rightmost '0' after the decimal point + // determines the range of digits that are always present in the output + // string. + // + // # - Digit placeholder. If the value being + // formatted has a digit in the position where the '#' appears in the format + // string, then that digit is copied to the output string. Otherwise, nothing + // is stored in that position in the output string. + // + // . - Decimal point. The first '.' character + // in the format string determines the location of the decimal separator in the + // formatted value; any additional '.' characters are ignored. The actual + // character used as a the decimal separator in the output string is given by + // the NumberFormatInfo used to format the number. + // + // , - Thousand separator and number scaling. + // The ',' character serves two purposes. First, if the format string contains + // a ',' character between two digit placeholders (0 or #) and to the left of + // the decimal point if one is present, then the output will have thousand + // separators inserted between each group of three digits to the left of the + // decimal separator. The actual character used as a the decimal separator in + // the output string is given by the NumberFormatInfo used to format the + // number. Second, if the format string contains one or more ',' characters + // immediately to the left of the decimal point, or after the last digit + // placeholder if there is no decimal point, then the number will be divided by + // 1000 times the number of ',' characters before it is formatted. For example, + // the format string '0,,' will represent 100 million as just 100. Use of the + // ',' character to indicate scaling does not also cause the formatted number + // to have thousand separators. Thus, to scale a number by 1 million and insert + // thousand separators you would use the format string '#,##0,,'. + // + // % - Percentage placeholder. The presence of + // a '%' character in the format string causes the number to be multiplied by + // 100 before it is formatted. The '%' character itself is inserted in the + // output string where it appears in the format string. + // + // E+ E- e+ e- - Scientific notation. + // If any of the strings 'E+', 'E-', 'e+', or 'e-' are present in the format + // string and are immediately followed by at least one '0' character, then the + // number is formatted using scientific notation with an 'E' or 'e' inserted + // between the number and the exponent. The number of '0' characters following + // the scientific notation indicator determines the minimum number of digits to + // output for the exponent. The 'E+' and 'e+' formats indicate that a sign + // character (plus or minus) should always precede the exponent. The 'E-' and + // 'e-' formats indicate that a sign character should only precede negative + // exponents. + // + // \ - Literal character. A backslash character + // causes the next character in the format string to be copied to the output + // string as-is. The backslash itself isn't copied, so to place a backslash + // character in the output string, use two backslashes (\\) in the format + // string. + // + // 'ABC' "ABC" - Literal string. Characters + // enclosed in single or double quotation marks are copied to the output string + // as-is and do not affect formatting. + // + // ; - Section separator. The ';' character is + // used to separate sections for positive, negative, and zero numbers in the + // format string. + // + // Other - All other characters are copied to + // the output string in the position they appear. + // + // For fixed point formats (formats not containing an 'E+', 'E-', 'e+', or + // 'e-'), the number is rounded to as many decimal places as there are digit + // placeholders to the right of the decimal point. If the format string does + // not contain a decimal point, the number is rounded to the nearest + // integer. If the number has more digits than there are digit placeholders to + // the left of the decimal point, the extra digits are copied to the output + // string immediately before the first digit placeholder. + // + // For scientific formats, the number is rounded to as many significant digits + // as there are digit placeholders in the format string. + // + // To allow for different formatting of positive, negative, and zero values, a + // user-defined format string may contain up to three sections separated by + // semicolons. The results of having one, two, or three sections in the format + // string are described in the table below. + // + // Sections: + // + // One - The format string applies to all values. + // + // Two - The first section applies to positive values + // and zeros, and the second section applies to negative values. If the number + // to be formatted is negative, but becomes zero after rounding according to + // the format in the second section, then the resulting zero is formatted + // according to the first section. + // + // Three - The first section applies to positive + // values, the second section applies to negative values, and the third section + // applies to zeros. The second section may be left empty (by having no + // characters between the semicolons), in which case the first section applies + // to all non-zero values. If the number to be formatted is non-zero, but + // becomes zero after rounding according to the format in the first or second + // section, then the resulting zero is formatted according to the third + // section. + // + // For both standard and user-defined formatting operations on values of type + // float and double, if the value being formatted is a NaN (Not + // a Number) or a positive or negative infinity, then regardless of the format + // string, the resulting string is given by the NaNSymbol, + // PositiveInfinitySymbol, or NegativeInfinitySymbol property of + // the NumberFormatInfo used to format the number. + + internal static partial class Number + { + internal const int DecimalPrecision = 29; // Decimal.DecCalc also uses this value + + // SinglePrecision and DoublePrecision represent the maximum number of digits required + // to guarantee that any given Single or Double can roundtrip. Some numbers may require + // less, but none will require more. + private const int SinglePrecision = 9; + private const int DoublePrecision = 17; + + // SinglePrecisionCustomFormat and DoublePrecisionCustomFormat are used to ensure that + // custom format strings return the same string as in previous releases when the format + // would return x digits or less (where x is the value of the corresponding constant). + // In order to support more digits, we would need to update ParseFormatSpecifier to pre-parse + // the format and determine exactly how many digits are being requested and whether they + // represent "significant digits" or "digits after the decimal point". + private const int SinglePrecisionCustomFormat = 7; + private const int DoublePrecisionCustomFormat = 15; + + private const int DefaultPrecisionExponentialFormat = 6; + + private const int MaxUInt32DecDigits = 10; + private const int CharStackBufferSize = 32; + private const string PosNumberFormat = "#"; + + private static readonly string[] s_singleDigitStringCache = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + + private static readonly string[] s_posCurrencyFormats = + { + "$#", "#$", "$ #", "# $" + }; + + private static readonly string[] s_negCurrencyFormats = + { + "($#)", "-$#", "$-#", "$#-", + "(#$)", "-#$", "#-$", "#$-", + "-# $", "-$ #", "# $-", "$ #-", + "$ -#", "#- $", "($ #)", "(# $)" + }; + + private static readonly string[] s_posPercentFormats = + { + "# %", "#%", "%#", "% #" + }; + + private static readonly string[] s_negPercentFormats = + { + "-# %", "-#%", "-%#", + "%-#", "%#-", + "#-%", "#%-", + "-% #", "# %-", "% #-", + "% -#", "#- %" + }; + + private static readonly string[] s_negNumberFormats = + { + "(#)", "-#", "- #", "#-", "# -", + }; + + public static unsafe string FormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info) + { + char fmt = ParseFormatSpecifier(format, out int digits); + + byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); + + DecimalToNumber(ref value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + + return sb.ToString(); + } + + public static unsafe bool TryFormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) + { + char fmt = ParseFormatSpecifier(format, out int digits); + + byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); + + DecimalToNumber(ref value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + + return sb.TryCopyTo(destination, out charsWritten); + } + + internal static unsafe void DecimalToNumber(ref decimal d, ref NumberBuffer number) + { + byte* buffer = number.GetDigitsPointer(); + number.DigitsCount = DecimalPrecision; + number.IsNegative = d.IsNegative(); + + byte* p = buffer + DecimalPrecision; + while ((d.Mid() | d.High()) != 0) + { + p = UInt32ToDecChars(p, DecimalEx.DecDivMod1E9(ref d), 9); + } + p = UInt32ToDecChars(p, d.Low(), 0); + + int i = (int)((buffer + DecimalPrecision) - p); + + number.DigitsCount = i; + number.Scale = i - d.Scale(); + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + { + *dst++ = *p++; + } + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + public static string FormatDouble(double value, string format, NumberFormatInfo info) + { + Span stackBuffer = stackalloc char[CharStackBufferSize]; + var sb = new ValueStringBuilder(stackBuffer); + return FormatDouble(ref sb, value, format.AsSpan(), info) ?? sb.ToString(); + } + + public static bool TryFormatDouble(double value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) + { + Span stackBuffer = stackalloc char[CharStackBufferSize]; + var sb = new ValueStringBuilder(stackBuffer); + string s = FormatDouble(ref sb, value, format, info); + return s != null ? + TryCopyTo(s, destination, out charsWritten) : + sb.TryCopyTo(destination, out charsWritten); + } + + private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int precision, NumberFormatInfo info, out bool isSignificantDigits) + { + if (fmt == 0) + { + isSignificantDigits = true; + return precision; + } + + int maxDigits = precision; + + switch (fmt) + { + case 'C': + case 'c': + { + // The currency format uses the precision specifier to indicate the number of + // decimal digits to format. This defaults to NumberFormatInfo.CurrencyDecimalDigits. + + if (precision == -1) + { + precision = info.CurrencyDecimalDigits; + } + isSignificantDigits = false; + + break; + } + + case 'E': + case 'e': + { + // The exponential format uses the precision specifier to indicate the number of + // decimal digits to format. This defaults to 6. However, the exponential format + // also always formats a single integral digit, so we need to increase the precision + // specifier and treat it as the number of significant digits to account for this. + + if (precision == -1) + { + precision = DefaultPrecisionExponentialFormat; + } + + precision++; + isSignificantDigits = true; + + break; + } + + case 'F': + case 'f': + case 'N': + case 'n': + { + // The fixed-point and number formats use the precision specifier to indicate the number + // of decimal digits to format. This defaults to NumberFormatInfo.NumberDecimalDigits. + + if (precision == -1) + { + precision = info.NumberDecimalDigits; + } + isSignificantDigits = false; + + break; + } + + case 'G': + case 'g': + { + // The general format uses the precision specifier to indicate the number of significant + // digits to format. This defaults to the shortest roundtrippable string. Additionally, + // given that we can't return zero significant digits, we treat 0 as returning the shortest + // roundtrippable string as well. + + if (precision == 0) + { + precision = -1; + } + isSignificantDigits = true; + + break; + } + + case 'P': + case 'p': + { + // The percent format uses the precision specifier to indicate the number of + // decimal digits to format. This defaults to NumberFormatInfo.PercentDecimalDigits. + // However, the percent format also always multiplies the number by 100, so we need + // to increase the precision specifier to ensure we get the appropriate number of digits. + + if (precision == -1) + { + precision = info.PercentDecimalDigits; + } + + precision += 2; + isSignificantDigits = false; + + break; + } + + case 'R': + case 'r': + { + // The roundtrip format ignores the precision specifier and always returns the shortest + // roundtrippable string. + + precision = -1; + isSignificantDigits = true; + + break; + } + + default: + { + throw new FormatException("SR.Argument_BadFormatSpecifier"); + } + } + + return maxDigits; + } + + /// Formats the specified value according to the specified format and info. + /// + /// Non-null if an existing string can be returned, in which case the builder will be unmodified. + /// Null if no existing string was returned, in which case the formatted output is in the builder. + /// + private static unsafe string FormatDouble(ref ValueStringBuilder sb, double value, ReadOnlySpan format, NumberFormatInfo info) + { + if (!FloatEx.IsFinite(value)) + { + if (double.IsNaN(value)) + { + return info.NaNSymbol; + } + + return FloatEx.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; + } + + char fmt = ParseFormatSpecifier(format, out int precision); + byte* pDigits = stackalloc byte[DoubleNumberBufferLength]; + + if (fmt == '\0') + { + // For back-compat we currently specially treat the precision for custom + // format specifiers. The constant has more details as to why. + precision = DoublePrecisionCustomFormat; + } + + NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, DoubleNumberBufferLength); + number.IsNegative = FloatEx.IsNegative(value); + + // We need to track the original precision requested since some formats + // accept values like 0 and others may require additional fixups. + int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(fmt, ref precision, info, out bool isSignificantDigits); + + if ((value != 0.0) && (!isSignificantDigits || !Grisu3.TryRunDouble(value, precision, ref number))) + { + Dragon4Double(value, precision, isSignificantDigits, ref number); + } + + number.CheckConsistency(); + + // When the number is known to be roundtrippable (either because we requested it be, or + // because we know we have enough digits to satisfy roundtrippability), we should validate + // that the number actually roundtrips back to the original result. + + Debug.Assert(((precision != -1) && (precision < DoublePrecision)) || (BitConverter.DoubleToInt64Bits(value) == BitConverter.DoubleToInt64Bits(NumberToDouble(ref number)))); + + if (fmt != 0) + { + if (precision == -1) + { + Debug.Assert((fmt == 'G') || (fmt == 'g') || (fmt == 'R') || (fmt == 'r')); + + // For the roundtrip and general format specifiers, when returning the shortest roundtrippable + // string, we need to update the maximum number of digits to be the greater of number.DigitsCount + // or DoublePrecision. This ensures that we continue returning "pretty" strings for values with + // less digits. One example this fixes is "-60", which would otherwise be formatted as "-6E+01" + // since DigitsCount would be 1 and the formatter would almost immediately switch to scientific notation. + + nMaxDigits = Math.Max(number.DigitsCount, DoublePrecision); + } + NumberToString(ref sb, ref number, fmt, nMaxDigits, info); + } + else + { + Debug.Assert(precision == DoublePrecisionCustomFormat); + NumberToStringFormat(ref sb, ref number, format, info); + } + return null; + } + + public static string FormatSingle(float value, string format, NumberFormatInfo info) + { + Span stackBuffer = stackalloc char[CharStackBufferSize]; + var sb = new ValueStringBuilder(stackBuffer); + return FormatSingle(ref sb, value, format.AsSpan(), info) ?? sb.ToString(); + } + + public static bool TryFormatSingle(float value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) + { + Span stackBuffer = stackalloc char[CharStackBufferSize]; + var sb = new ValueStringBuilder(stackBuffer); + string s = FormatSingle(ref sb, value, format, info); + return s != null ? + TryCopyTo(s, destination, out charsWritten) : + sb.TryCopyTo(destination, out charsWritten); + } + + /// Formats the specified value according to the specified format and info. + /// + /// Non-null if an existing string can be returned, in which case the builder will be unmodified. + /// Null if no existing string was returned, in which case the formatted output is in the builder. + /// + private static unsafe string FormatSingle(ref ValueStringBuilder sb, float value, ReadOnlySpan format, NumberFormatInfo info) + { + if (!FloatEx.IsFinite(value)) + { + if (float.IsNaN(value)) + { + return info.NaNSymbol; + } + + return FloatEx.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; + } + + char fmt = ParseFormatSpecifier(format, out int precision); + byte* pDigits = stackalloc byte[SingleNumberBufferLength]; + + if (fmt == '\0') + { + // For back-compat we currently specially treat the precision for custom + // format specifiers. The constant has more details as to why. + precision = SinglePrecisionCustomFormat; + } + + NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, SingleNumberBufferLength); + number.IsNegative = FloatEx.IsNegative(value); + + // We need to track the original precision requested since some formats + // accept values like 0 and others may require additional fixups. + int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(fmt, ref precision, info, out bool isSignificantDigits); + + if ((value != 0.0f) && (!isSignificantDigits || !Grisu3.TryRunSingle(value, precision, ref number))) + { + Dragon4Single(value, precision, isSignificantDigits, ref number); + } + + number.CheckConsistency(); + + // When the number is known to be roundtrippable (either because we requested it be, or + // because we know we have enough digits to satisfy roundtrippability), we should validate + // that the number actually roundtrips back to the original result. + + Debug.Assert(((precision != -1) && (precision < SinglePrecision)) || (SingleToInt32Bits(value) == SingleToInt32Bits(NumberToSingle(ref number)))); + + if (fmt != 0) + { + if (precision == -1) + { + Debug.Assert((fmt == 'G') || (fmt == 'g') || (fmt == 'R') || (fmt == 'r')); + + // For the roundtrip and general format specifiers, when returning the shortest roundtrippable + // string, we need to update the maximum number of digits to be the greater of number.DigitsCount + // or SinglePrecision. This ensures that we continue returning "pretty" strings for values with + // less digits. One example this fixes is "-60", which would otherwise be formatted as "-6E+01" + // since DigitsCount would be 1 and the formatter would almost immediately switch to scientific notation. + + nMaxDigits = Math.Max(number.DigitsCount, SinglePrecision); + } + NumberToString(ref sb, ref number, fmt, nMaxDigits, info); + } + else + { + Debug.Assert(precision == SinglePrecisionCustomFormat); + NumberToStringFormat(ref sb, ref number, format, info); + } + return null; + } + + private static bool TryCopyTo(string source, Span destination, out int charsWritten) + { + Debug.Assert(source != null); + + if (source.AsSpan().TryCopyTo(destination)) + { + charsWritten = source.Length; + return true; + } + + charsWritten = 0; + return false; + } + + public static unsafe string FormatInt32(int value, ReadOnlySpan format, IFormatProvider provider) + { + // Fast path for default format with a non-negative value + if (value >= 0 && format.Length == 0) + { + return UInt32ToDecStr((uint)value, digits: -1); + } + + char fmt = ParseFormatSpecifier(format, out int 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 ? + UInt32ToDecStr((uint)value, digits) : + NegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign); + } + 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 Int32ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Int32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); + + Int32ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.ToString(); + } + } + + public static unsafe bool TryFormatInt32(int value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) + { + // Fast path for default format with a non-negative value + if (value >= 0 && format.Length == 0) + { + return TryUInt32ToDecStr((uint)value, digits: -1, destination, out charsWritten); + } + + char fmt = ParseFormatSpecifier(format, out int 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, NumberFormatInfo.GetInstance(provider).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 + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Int32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); + + Int32ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.TryCopyTo(destination, out charsWritten); + } + } + + public static unsafe string FormatUInt32(uint value, ReadOnlySpan format, IFormatProvider provider) + { + // Fast path for default format + if (format.Length == 0) + { + return UInt32ToDecStr(value, digits: -1); + } + + char fmt = ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') + { + return UInt32ToDecStr(value, digits); + } + 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 Int32ToHexStr((int)value, (char)(fmt - ('X' - 'A' + 10)), digits); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); + + UInt32ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.ToString(); + } + } + + public static unsafe bool TryFormatUInt32(uint value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) + { + // Fast path for default format + if (format.Length == 0) + { + return TryUInt32ToDecStr(value, digits: -1, destination, out charsWritten); + } + + char fmt = ParseFormatSpecifier(format, out int 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 + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); + + UInt32ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.TryCopyTo(destination, out charsWritten); + } + } + + public static unsafe string FormatInt64(long value, ReadOnlySpan format, IFormatProvider provider) + { + // Fast path for default format with a non-negative value + if (value >= 0 && format.Length == 0) + { + return UInt64ToDecStr((ulong)value, digits: -1); + } + + char fmt = ParseFormatSpecifier(format, out int 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 ? + UInt64ToDecStr((ulong)value, digits) : + NegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign); + } + 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 Int64ToHexStr(value, (char)(fmt - ('X' - 'A' + 10)), digits); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Int64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); + + Int64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.ToString(); + } + } + + public static unsafe bool TryFormatInt64(long value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) + { + // Fast path for default format with a non-negative value + if (value >= 0 && format.Length == 0) + { + return TryUInt64ToDecStr((ulong)value, digits: -1, destination, out charsWritten); + } + + char fmt = ParseFormatSpecifier(format, out int 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, NumberFormatInfo.GetInstance(provider).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 + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Int64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); + + Int64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.TryCopyTo(destination, out charsWritten); + } + } + + public static unsafe string FormatUInt64(ulong value, ReadOnlySpan format, IFormatProvider provider) + { + // Fast path for default format + if (format.Length == 0) + { + return UInt64ToDecStr(value, digits: -1); + } + + char fmt = ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + if ((fmtUpper == 'G' && digits < 1) || fmtUpper == 'D') + { + return UInt64ToDecStr(value, digits); + } + 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 Int64ToHexStr((long)value, (char)(fmt - ('X' - 'A' + 10)), digits); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); + + UInt64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.ToString(); + } + } + + public static unsafe bool TryFormatUInt64(ulong value, ReadOnlySpan format, IFormatProvider provider, Span destination, out int charsWritten) + { + // Fast path for default format + if (format.Length == 0) + { + return TryUInt64ToDecStr(value, digits: -1, destination, out charsWritten); + } + + char fmt = ParseFormatSpecifier(format, out int 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 + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); + + UInt64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[CharStackBufferSize]; + ValueStringBuilder sb = new ValueStringBuilder(new Span(stackPtr, CharStackBufferSize)); + + if (fmt != 0) + { + NumberToString(ref sb, ref number, fmt, digits, info); + } + else + { + NumberToStringFormat(ref sb, ref number, format, info); + } + return sb.TryCopyTo(destination, out charsWritten); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // called from only one location + private static unsafe void Int32ToNumber(int value, ref NumberBuffer number) + { + number.DigitsCount = Int32Precision; + + if (value >= 0) + { + number.IsNegative = false; + } + else + { + number.IsNegative = true; + value = -value; + } + + byte* buffer = number.GetDigitsPointer(); + byte* p = UInt32ToDecChars(buffer + Int32Precision, (uint)value, 0); + + int i = (int)(buffer + Int32Precision - p); + + number.DigitsCount = i; + number.Scale = i; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + *dst++ = *p++; + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + private static unsafe string NegativeInt32ToDecStr(int value, int digits, string sNegative) + { + Debug.Assert(value < 0); + + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; + string result = FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, string sNegative, Span destination, out int charsWritten) + { + Debug.Assert(value < 0); + + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe string Int32ToHexStr(int value, char hexBase, int digits) + { + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); + string result = FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span destination, out int charsWritten) + { + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe char* Int32ToHexChars(char* buffer, uint value, int hexBase, int digits) + { + while (--digits >= 0 || value != 0) + { + byte digit = (byte)(value & 0xF); + *(--buffer) = (char)(digit + (digit < 10 ? (byte)'0' : hexBase)); + value >>= 4; + } + return buffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // called from only one location + private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) + { + number.DigitsCount = UInt32Precision; + number.IsNegative = false; + + byte* buffer = number.GetDigitsPointer(); + byte* p = UInt32ToDecChars(buffer + UInt32Precision, value, 0); + + int i = (int)(buffer + UInt32Precision - p); + + number.DigitsCount = i; + number.Scale = i; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + *dst++ = *p++; + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + internal static unsafe byte* UInt32ToDecChars(byte* bufferEnd, uint value, int digits) + { + while (--digits >= 0 || value != 0) + { + value = MathEx.DivRem(value, 10, out uint remainder); + *(--bufferEnd) = (byte)(remainder + '0'); + } + return bufferEnd; + } + + internal static unsafe char* UInt32ToDecChars(char* bufferEnd, uint value, int digits) + { + while (--digits >= 0 || value != 0) + { + value = MathEx.DivRem(value, 10, out uint remainder); + *(--bufferEnd) = (char)(remainder + '0'); + } + return bufferEnd; + } + + internal static unsafe string UInt32ToDecStr(uint value, int digits) + { + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); + + // For single-digit values that are very common, especially 0 and 1, just return cached strings. + if (bufferLength == 1) + { + return s_singleDigitStringCache[value]; + } + + string result = FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = buffer + bufferLength; + if (digits <= 1) + { + do + { + value = MathEx.DivRem(value, 10, out uint remainder); + *(--p) = (char)(remainder + '0'); + } + while (value != 0); + } + else + { + p = UInt32ToDecChars(p, value, digits); + } + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span destination, out int charsWritten) + { + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = buffer + bufferLength; + if (digits <= 1) + { + do + { + value = MathEx.DivRem(value, 10, out uint remainder); + *(--p) = (char)(remainder + '0'); + } + while (value != 0); + } + else + { + p = UInt32ToDecChars(p, value, digits); + } + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe void Int64ToNumber(long input, ref NumberBuffer number) + { + ulong value = (ulong)input; + number.IsNegative = input < 0; + number.DigitsCount = Int64Precision; + if (number.IsNegative) + { + value = (ulong)(-input); + } + + byte* buffer = number.GetDigitsPointer(); + byte* p = buffer + Int64Precision; + while (High32(value) != 0) + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + p = UInt32ToDecChars(p, Low32(value), 0); + + int i = (int)(buffer + Int64Precision - p); + + number.DigitsCount = i; + number.Scale = i; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + *dst++ = *p++; + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + private static unsafe string NegativeInt64ToDecStr(long input, int digits, string sNegative) + { + Debug.Assert(input < 0); + + if (digits < 1) + { + digits = 1; + } + + ulong value = (ulong)(-input); + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)) + sNegative.Length; + string result = FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = buffer + bufferLength; + while (High32(value) != 0) + { + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + digits -= 9; + } + p = UInt32ToDecChars(p, Low32(value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryNegativeInt64ToDecStr(long input, int digits, string sNegative, Span destination, out int charsWritten) + { + Debug.Assert(input < 0); + + if (digits < 1) + { + digits = 1; + } + + ulong value = (ulong)(-input); + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((ulong)(-input))) + sNegative.Length; + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = buffer + bufferLength; + while (High32(value) != 0) + { + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + digits -= 9; + } + p = UInt32ToDecChars(p, Low32(value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe string Int64ToHexStr(long value, char hexBase, int digits) + { + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); + string result = FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = buffer + bufferLength; + if (High32((ulong)value) != 0) + { + p = Int32ToHexChars(p, Low32((ulong)value), hexBase, 8); + p = Int32ToHexChars(p, High32((ulong)value), hexBase, digits - 8); + } + else + { + p = Int32ToHexChars(p, Low32((ulong)value), hexBase, Math.Max(digits, 1)); + } + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span destination, out int charsWritten) + { + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = buffer + bufferLength; + if (High32((ulong)value) != 0) + { + p = Int32ToHexChars(p, Low32((ulong)value), hexBase, 8); + p = Int32ToHexChars(p, High32((ulong)value), hexBase, digits - 8); + } + else + { + p = Int32ToHexChars(p, Low32((ulong)value), hexBase, Math.Max(digits, 1)); + } + Debug.Assert(p == buffer); + } + return true; + } + + private static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number) + { + number.DigitsCount = UInt64Precision; + number.IsNegative = false; + + byte* buffer = number.GetDigitsPointer(); + byte* p = buffer + UInt64Precision; + + while (High32(value) != 0) + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + p = UInt32ToDecChars(p, Low32(value), 0); + + int i = (int)(buffer + UInt64Precision - p); + + number.DigitsCount = i; + number.Scale = i; + + byte* dst = number.GetDigitsPointer(); + while (--i >= 0) + *dst++ = *p++; + *dst = (byte)('\0'); + + number.CheckConsistency(); + } + + internal static unsafe string UInt64ToDecStr(ulong value, int digits) + { + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); + + // For single-digit values that are very common, especially 0 and 1, just return cached strings. + if (bufferLength == 1) + { + return s_singleDigitStringCache[value]; + } + + string result = FastAllocateString(bufferLength); + fixed (char* buffer = result) + { + char* p = buffer + bufferLength; + while (High32(value) != 0) + { + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + digits -= 9; + } + p = UInt32ToDecChars(p, Low32(value), digits); + Debug.Assert(p == buffer); + } + return result; + } + + private static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span destination, out int charsWritten) + { + if (digits < 1) + digits = 1; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (char* buffer = &MemoryMarshal.GetReference(destination)) + { + char* p = buffer + bufferLength; + while (High32(value) != 0) + { + p = UInt32ToDecChars(p, Int64DivMod1E9(ref value), 9); + digits -= 9; + } + p = UInt32ToDecChars(p, Low32(value), digits); + Debug.Assert(p == buffer); + } + return true; + } + + internal static unsafe char ParseFormatSpecifier(ReadOnlySpan format, out int digits) + { + char c = default; + if (format.Length > 0) + { + // If the format begins with a symbol, see if it's a standard format + // with or without a specified number of digits. + c = format[0]; + if ((uint)(c - 'A') <= 'Z' - 'A' || + (uint)(c - 'a') <= 'z' - 'a') + { + // Fast path for sole symbol, e.g. "D" + if (format.Length == 1) + { + digits = -1; + return c; + } + + if (format.Length == 2) + { + // Fast path for symbol and single digit, e.g. "X4" + int d = format[1] - '0'; + if ((uint)d < 10) + { + digits = d; + return c; + } + } + else if (format.Length == 3) + { + // Fast path for symbol and double digit, e.g. "F12" + int d1 = format[1] - '0', d2 = format[2] - '0'; + if ((uint)d1 < 10 && (uint)d2 < 10) + { + digits = d1 * 10 + d2; + return c; + } + } + + // Fallback for symbol and any length digits. The digits value must be >= 0 && <= 99, + // but it can begin with any number of 0s, and thus we may need to check more than two + // digits. Further, for compat, we need to stop when we hit a null char. + int n = 0; + int i = 1; + while (i < format.Length && (((uint)format[i] - '0') < 10) && n < 10) + { + n = (n * 10) + format[i++] - '0'; + } + + // If we're at the end of the digits rather than having stopped because we hit something + // other than a digit or overflowed, return the standard format info. + if (i == format.Length || format[i] == '\0') + { + digits = n; + return c; + } + } + } + + // Default empty format to be "G"; custom format is signified with '\0'. + digits = -1; + return format.Length == 0 || c == '\0' ? // For compat, treat '\0' as the end of the specifier, even if the specifier extends beyond it. + 'G' : + '\0'; + } + + internal static unsafe void NumberToString(ref ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info) + { + number.CheckConsistency(); + bool isCorrectlyRounded = (number.Kind == NumberBufferKind.FloatingPoint); + + switch (format) + { + case 'C': + case 'c': + { + if (nMaxDigits < 0) + nMaxDigits = info.CurrencyDecimalDigits; + + RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); // Don't change this line to use digPos since digCount could have its sign changed. + + FormatCurrency(ref sb, ref number, nMaxDigits, info); + + break; + } + + case 'F': + case 'f': + { + if (nMaxDigits < 0) + nMaxDigits = info.NumberDecimalDigits; + + RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); + + if (number.IsNegative) + sb.Append(info.NegativeSign); + + FormatFixed(ref sb, ref number, nMaxDigits, null, info.NumberDecimalSeparator, null); + + break; + } + + case 'N': + case 'n': + { + if (nMaxDigits < 0) + nMaxDigits = info.NumberDecimalDigits; // Since we are using digits in our calculation + + RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); + + FormatNumber(ref sb, ref number, nMaxDigits, info); + + break; + } + + case 'E': + case 'e': + { + if (nMaxDigits < 0) + nMaxDigits = DefaultPrecisionExponentialFormat; + nMaxDigits++; + + RoundNumber(ref number, nMaxDigits, isCorrectlyRounded); + + if (number.IsNegative) + sb.Append(info.NegativeSign); + + FormatScientific(ref sb, ref number, nMaxDigits, info, format); + + break; + } + + case 'G': + case 'g': + { + bool noRounding = false; + if (nMaxDigits < 1) + { + if ((number.Kind == NumberBufferKind.Decimal) && (nMaxDigits == -1)) + { + noRounding = true; // Turn off rounding for ECMA compliance to output trailing 0's after decimal as significant + + if (number.Digits[0] == 0) + { + // -0 should be formatted as 0 for decimal. This is normally handled by RoundNumber (which we are skipping) + goto SkipSign; + } + + goto SkipRounding; + } + else + { + // This ensures that the PAL code pads out to the correct place even when we use the default precision + nMaxDigits = number.DigitsCount; + } + } + + RoundNumber(ref number, nMaxDigits, isCorrectlyRounded); + + SkipRounding: + if (number.IsNegative) + sb.Append(info.NegativeSign); + + SkipSign: + FormatGeneral(ref sb, ref number, nMaxDigits, info, (char)(format - ('G' - 'E')), noRounding); + + break; + } + + case 'P': + case 'p': + { + if (nMaxDigits < 0) + nMaxDigits = info.PercentDecimalDigits; + number.Scale += 2; + + RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded); + + FormatPercent(ref sb, ref number, nMaxDigits, info); + + break; + } + + case 'R': + case 'r': + { + if (number.Kind != NumberBufferKind.FloatingPoint) + { + goto default; + } + + format = (char)(format - ('R' - 'G')); + Debug.Assert((format == 'G') || (format == 'g')); + goto case 'G'; + } + + default: + throw new FormatException("SR.Argument_BadFormatSpecifier"); + } + } + + internal static unsafe void NumberToStringFormat(ref ValueStringBuilder sb, ref NumberBuffer number, ReadOnlySpan format, NumberFormatInfo info) + { + number.CheckConsistency(); + + int digitCount; + int decimalPos; + int firstDigit; + int lastDigit; + int digPos; + bool scientific; + int thousandPos; + int thousandCount = 0; + bool thousandSeps; + int scaleAdjust; + int adjust; + + int section; + int src; + byte* dig = number.GetDigitsPointer(); + char ch; + + section = FindSection(format, dig[0] == 0 ? 2 : number.IsNegative ? 1 : 0); + + while (true) + { + digitCount = 0; + decimalPos = -1; + firstDigit = 0x7FFFFFFF; + lastDigit = 0; + scientific = false; + thousandPos = -1; + thousandSeps = false; + scaleAdjust = 0; + src = section; + + fixed (char* pFormat = &MemoryMarshal.GetReference(format)) + { + while (src < format.Length && (ch = pFormat[src++]) != 0 && ch != ';') + { + switch (ch) + { + case '#': + digitCount++; + break; + case '0': + if (firstDigit == 0x7FFFFFFF) + firstDigit = digitCount; + digitCount++; + lastDigit = digitCount; + break; + case '.': + if (decimalPos < 0) + decimalPos = digitCount; + break; + case ',': + if (digitCount > 0 && decimalPos < 0) + { + if (thousandPos >= 0) + { + if (thousandPos == digitCount) + { + thousandCount++; + break; + } + thousandSeps = true; + } + thousandPos = digitCount; + thousandCount = 1; + } + break; + case '%': + scaleAdjust += 2; + break; + case '\x2030': + scaleAdjust += 3; + break; + case '\'': + case '"': + while (src < format.Length && pFormat[src] != 0 && pFormat[src++] != ch) + ; + break; + case '\\': + if (src < format.Length && pFormat[src] != 0) + src++; + break; + case 'E': + case 'e': + if ((src < format.Length && pFormat[src] == '0') || + (src + 1 < format.Length && (pFormat[src] == '+' || pFormat[src] == '-') && pFormat[src + 1] == '0')) + { + while (++src < format.Length && pFormat[src] == '0') + ; + scientific = true; + } + break; + } + } + } + + if (decimalPos < 0) + decimalPos = digitCount; + + if (thousandPos >= 0) + { + if (thousandPos == decimalPos) + scaleAdjust -= thousandCount * 3; + else + thousandSeps = true; + } + + if (dig[0] != 0) + { + number.Scale += scaleAdjust; + int pos = scientific ? digitCount : number.Scale + digitCount - decimalPos; + RoundNumber(ref number, pos, isCorrectlyRounded: false); + if (dig[0] == 0) + { + src = FindSection(format, 2); + if (src != section) + { + section = src; + continue; + } + } + } + else + { + if (number.Kind != NumberBufferKind.FloatingPoint) + { + // The integer types don't have a concept of -0 and decimal always format -0 as 0 + number.IsNegative = false; + } + number.Scale = 0; // Decimals with scale ('0.00') should be rounded. + } + + break; + } + + firstDigit = firstDigit < decimalPos ? decimalPos - firstDigit : 0; + lastDigit = lastDigit > decimalPos ? decimalPos - lastDigit : 0; + if (scientific) + { + digPos = decimalPos; + adjust = 0; + } + else + { + digPos = number.Scale > decimalPos ? number.Scale : decimalPos; + adjust = number.Scale - decimalPos; + } + src = section; + + // Adjust can be negative, so we make this an int instead of an unsigned int. + // Adjust represents the number of characters over the formatting e.g. format string is "0000" and you are trying to + // format 100000 (6 digits). Means adjust will be 2. On the other hand if you are trying to format 10 adjust will be + // -2 and we'll need to fixup these digits with 0 padding if we have 0 formatting as in this example. + Span thousandsSepPos = stackalloc int[4]; + int thousandsSepCtr = -1; + + if (thousandSeps) + { + // We need to precompute this outside the number formatting loop + if (info.NumberGroupSeparator.Length > 0) + { + // We need this array to figure out where to insert the thousands separator. We would have to traverse the string + // backwards. PIC formatting always traverses forwards. These indices are precomputed to tell us where to insert + // the thousands separator so we can get away with traversing forwards. Note we only have to compute up to digPos. + // The max is not bound since you can have formatting strings of the form "000,000..", and this + // should handle that case too. + + int[] groupDigits = info.NumberGroupSizes; + + int groupSizeIndex = 0; // Index into the groupDigits array. + int groupTotalSizeCount = 0; + int groupSizeLen = groupDigits.Length; // The length of groupDigits array. + if (groupSizeLen != 0) + groupTotalSizeCount = groupDigits[groupSizeIndex]; // The current running total of group size. + int groupSize = groupTotalSizeCount; + + int totalDigits = digPos + ((adjust < 0) ? adjust : 0); // Actual number of digits in o/p + int numDigits = (firstDigit > totalDigits) ? firstDigit : totalDigits; + while (numDigits > groupTotalSizeCount) + { + if (groupSize == 0) + break; + ++thousandsSepCtr; + if (thousandsSepCtr >= thousandsSepPos.Length) + { + var newThousandsSepPos = new int[thousandsSepPos.Length * 2]; + thousandsSepPos.CopyTo(newThousandsSepPos); + thousandsSepPos = newThousandsSepPos; + } + + thousandsSepPos[thousandsSepCtr] = groupTotalSizeCount; + if (groupSizeIndex < groupSizeLen - 1) + { + groupSizeIndex++; + groupSize = groupDigits[groupSizeIndex]; + } + groupTotalSizeCount += groupSize; + } + } + } + + if (number.IsNegative && (section == 0) && (number.Scale != 0)) + sb.Append(info.NegativeSign); + + bool decimalWritten = false; + + fixed (char* pFormat = &MemoryMarshal.GetReference(format)) + { + byte* cur = dig; + + while (src < format.Length && (ch = pFormat[src++]) != 0 && ch != ';') + { + if (adjust > 0) + { + switch (ch) + { + case '#': + case '0': + case '.': + while (adjust > 0) + { + // digPos will be one greater than thousandsSepPos[thousandsSepCtr] since we are at + // the character after which the groupSeparator needs to be appended. + sb.Append(*cur != 0 ? (char)(*cur++) : '0'); + if (thousandSeps && digPos > 1 && thousandsSepCtr >= 0) + { + if (digPos == thousandsSepPos[thousandsSepCtr] + 1) + { + sb.Append(info.NumberGroupSeparator); + thousandsSepCtr--; + } + } + digPos--; + adjust--; + } + break; + } + } + + switch (ch) + { + case '#': + case '0': + { + if (adjust < 0) + { + adjust++; + ch = digPos <= firstDigit ? '0' : '\0'; + } + else + { + ch = *cur != 0 ? (char)(*cur++) : digPos > lastDigit ? '0' : '\0'; + } + if (ch != 0) + { + sb.Append(ch); + if (thousandSeps && digPos > 1 && thousandsSepCtr >= 0) + { + if (digPos == thousandsSepPos[thousandsSepCtr] + 1) + { + sb.Append(info.NumberGroupSeparator); + thousandsSepCtr--; + } + } + } + + digPos--; + break; + } + case '.': + { + if (digPos != 0 || decimalWritten) + { + // For compatibility, don't echo repeated decimals + break; + } + // If the format has trailing zeros or the format has a decimal and digits remain + if (lastDigit < 0 || (decimalPos < digitCount && *cur != 0)) + { + sb.Append(info.NumberDecimalSeparator); + decimalWritten = true; + } + break; + } + case '\x2030': + sb.Append(info.PerMilleSymbol); + break; + case '%': + sb.Append(info.PercentSymbol); + break; + case ',': + break; + case '\'': + case '"': + while (src < format.Length && pFormat[src] != 0 && pFormat[src] != ch) + sb.Append(pFormat[src++]); + if (src < format.Length && pFormat[src] != 0) + src++; + break; + case '\\': + if (src < format.Length && pFormat[src] != 0) + sb.Append(pFormat[src++]); + break; + case 'E': + case 'e': + { + bool positiveSign = false; + int i = 0; + if (scientific) + { + if (src < format.Length && pFormat[src] == '0') + { + // Handles E0, which should format the same as E-0 + i++; + } + else if (src + 1 < format.Length && pFormat[src] == '+' && pFormat[src + 1] == '0') + { + // Handles E+0 + positiveSign = true; + } + else if (src + 1 < format.Length && pFormat[src] == '-' && pFormat[src + 1] == '0') + { + // Handles E-0 + // Do nothing, this is just a place holder s.t. we don't break out of the loop. + } + else + { + sb.Append(ch); + break; + } + + while (++src < format.Length && pFormat[src] == '0') + i++; + if (i > 10) + i = 10; + + int exp = dig[0] == 0 ? 0 : number.Scale - decimalPos; + FormatExponent(ref sb, info, exp, ch, i, positiveSign); + scientific = false; + } + else + { + sb.Append(ch); // Copy E or e to output + if (src < format.Length) + { + if (pFormat[src] == '+' || pFormat[src] == '-') + sb.Append(pFormat[src++]); + while (src < format.Length && pFormat[src] == '0') + sb.Append(pFormat[src++]); + } + } + break; + } + default: + sb.Append(ch); + break; + } + } + } + + if (number.IsNegative && (section == 0) && (number.Scale == 0) && (sb.Length > 0)) + sb.Insert(0, info.NegativeSign); + } + + private static void FormatCurrency(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) + { + string fmt = number.IsNegative ? + s_negCurrencyFormats[info.CurrencyNegativePattern] : + s_posCurrencyFormats[info.CurrencyPositivePattern]; + + foreach (char ch in fmt) + { + switch (ch) + { + case '#': + FormatFixed(ref sb, ref number, nMaxDigits, info.CurrencyGroupSizes, info.CurrencyDecimalSeparator, info.CurrencyGroupSeparator); + break; + case '-': + sb.Append(info.NegativeSign); + break; + case '$': + sb.Append(info.CurrencySymbol); + break; + default: + sb.Append(ch); + break; + } + } + } + + private static unsafe void FormatFixed(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, int[] groupDigits, string sDecimal, string sGroup) + { + int digPos = number.Scale; + byte* dig = number.GetDigitsPointer(); + + if (digPos > 0) + { + if (groupDigits != null) + { + Debug.Assert(sGroup != null, "Must be nulll when groupDigits != null"); + int groupSizeIndex = 0; // Index into the groupDigits array. + int bufferSize = digPos; // The length of the result buffer string. + int groupSize = 0; // The current group size. + + // Find out the size of the string buffer for the result. + if (groupDigits.Length != 0) // You can pass in 0 length arrays + { + int groupSizeCount = groupDigits[groupSizeIndex]; // The current total of group size. + + while (digPos > groupSizeCount) + { + groupSize = groupDigits[groupSizeIndex]; + if (groupSize == 0) + break; + + bufferSize += sGroup.Length; + if (groupSizeIndex < groupDigits.Length - 1) + groupSizeIndex++; + + groupSizeCount += groupDigits[groupSizeIndex]; + if (groupSizeCount < 0 || bufferSize < 0) + throw new ArgumentOutOfRangeException(); // If we overflow + } + + groupSize = groupSizeCount == 0 ? 0 : groupDigits[0]; // If you passed in an array with one entry as 0, groupSizeCount == 0 + } + + groupSizeIndex = 0; + int digitCount = 0; + int digLength = number.DigitsCount; + int digStart = (digPos < digLength) ? digPos : digLength; + fixed (char* spanPtr = &MemoryMarshal.GetReference(sb.AppendSpan(bufferSize))) + { + char* p = spanPtr + bufferSize - 1; + for (int i = digPos - 1; i >= 0; i--) + { + *(p--) = (i < digStart) ? (char)(dig[i]) : '0'; + + if (groupSize > 0) + { + digitCount++; + if ((digitCount == groupSize) && (i != 0)) + { + for (int j = sGroup.Length - 1; j >= 0; j--) + *(p--) = sGroup[j]; + + if (groupSizeIndex < groupDigits.Length - 1) + { + groupSizeIndex++; + groupSize = groupDigits[groupSizeIndex]; + } + digitCount = 0; + } + } + } + + Debug.Assert(p >= spanPtr - 1, "Underflow"); + dig += digStart; + } + } + else + { + do + { + sb.Append(*dig != 0 ? (char)(*dig++) : '0'); + } + while (--digPos > 0); + } + } + else + { + sb.Append('0'); + } + + if (nMaxDigits > 0) + { + Debug.Assert(sDecimal != null); + sb.Append(sDecimal); + if ((digPos < 0) && (nMaxDigits > 0)) + { + int zeroes = Math.Min(-digPos, nMaxDigits); + sb.Append('0', zeroes); + digPos += zeroes; + nMaxDigits -= zeroes; + } + + while (nMaxDigits > 0) + { + sb.Append((*dig != 0) ? (char)(*dig++) : '0'); + nMaxDigits--; + } + } + } + + private static void FormatNumber(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) + { + string fmt = number.IsNegative ? + s_negNumberFormats[info.NumberNegativePattern] : + PosNumberFormat; + + foreach (char ch in fmt) + { + switch (ch) + { + case '#': + FormatFixed(ref sb, ref number, nMaxDigits, info.NumberGroupSizes, info.NumberDecimalSeparator, info.NumberGroupSeparator); + break; + case '-': + sb.Append(info.NegativeSign); + break; + default: + sb.Append(ch); + break; + } + } + } + + private static unsafe void FormatScientific(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar) + { + byte* dig = number.GetDigitsPointer(); + + sb.Append((*dig != 0) ? (char)(*dig++) : '0'); + + if (nMaxDigits != 1) // For E0 we would like to suppress the decimal point + sb.Append(info.NumberDecimalSeparator); + + while (--nMaxDigits > 0) + sb.Append((*dig != 0) ? (char)(*dig++) : '0'); + + int e = number.Digits[0] == 0 ? 0 : number.Scale - 1; + FormatExponent(ref sb, info, e, expChar, 3, true); + } + + private static unsafe void FormatExponent(ref ValueStringBuilder sb, NumberFormatInfo info, int value, char expChar, int minDigits, bool positiveSign) + { + sb.Append(expChar); + + if (value < 0) + { + sb.Append(info.NegativeSign); + value = -value; + } + else + { + if (positiveSign) + sb.Append(info.PositiveSign); + } + + char* digits = stackalloc char[MaxUInt32DecDigits]; + char* p = UInt32ToDecChars(digits + MaxUInt32DecDigits, (uint)value, minDigits); + sb.Append(p, (int)(digits + MaxUInt32DecDigits - p)); + } + + private static unsafe void FormatGeneral(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar, bool bSuppressScientific) + { + int digPos = number.Scale; + bool scientific = false; + + if (!bSuppressScientific) + { + // Don't switch to scientific notation + if (digPos > nMaxDigits || digPos < -3) + { + digPos = 1; + scientific = true; + } + } + + byte* dig = number.GetDigitsPointer(); + + if (digPos > 0) + { + do + { + sb.Append((*dig != 0) ? (char)(*dig++) : '0'); + } while (--digPos > 0); + } + else + { + sb.Append('0'); + } + + if (*dig != 0 || digPos < 0) + { + sb.Append(info.NumberDecimalSeparator); + + while (digPos < 0) + { + sb.Append('0'); + digPos++; + } + + while (*dig != 0) + sb.Append((char)(*dig++)); + } + + if (scientific) + FormatExponent(ref sb, info, number.Scale - 1, expChar, 2, true); + } + + private static void FormatPercent(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info) + { + string fmt = number.IsNegative ? + s_negPercentFormats[info.PercentNegativePattern] : + s_posPercentFormats[info.PercentPositivePattern]; + + foreach (char ch in fmt) + { + switch (ch) + { + case '#': + FormatFixed(ref sb, ref number, nMaxDigits, info.PercentGroupSizes, info.PercentDecimalSeparator, info.PercentGroupSeparator); + break; + case '-': + sb.Append(info.NegativeSign); + break; + case '%': + sb.Append(info.PercentSymbol); + break; + default: + sb.Append(ch); + break; + } + } + } + + internal static unsafe void RoundNumber(ref NumberBuffer number, int pos, bool isCorrectlyRounded) + { + byte* dig = number.GetDigitsPointer(); + + int i = 0; + while (i < pos && dig[i] != '\0') + i++; + + if ((i == pos) && ShouldRoundUp(dig, i, number.Kind, isCorrectlyRounded)) + { + while (i > 0 && dig[i - 1] == '9') + i--; + + if (i > 0) + { + dig[i - 1]++; + } + else + { + number.Scale++; + dig[0] = (byte)('1'); + i = 1; + } + } + else + { + while (i > 0 && dig[i - 1] == '0') + i--; + } + + if (i == 0) + { + if (number.Kind != NumberBufferKind.FloatingPoint) + { + // The integer types don't have a concept of -0 and decimal always format -0 as 0 + number.IsNegative = false; + } + number.Scale = 0; // Decimals with scale ('0.00') should be rounded. + } + + dig[i] = (byte)('\0'); + number.DigitsCount = i; + number.CheckConsistency(); + + bool ShouldRoundUp(byte* _dig, int _i, NumberBufferKind numberKind, bool _isCorrectlyRounded) + { + // We only want to round up if the digit is greater than or equal to 5 and we are + // not rounding a floating-point number. If we are rounding a floating-point number + // we have one of two cases. + // + // In the case of a standard numeric-format specifier, the exact and correctly rounded + // string will have been produced. In this scenario, pos will have pointed to the + // terminating null for the buffer and so this will return false. + // + // However, in the case of a custom numeric-format specifier, we currently fall back + // to generating Single/DoublePrecisionCustomFormat digits and then rely on this + // function to round correctly instead. This can unfortunately lead to double-rounding + // bugs but is the best we have right now due to back-compat concerns. + + byte digit = _dig[_i]; + + if ((digit == '\0') || _isCorrectlyRounded) + { + // Fast path for the common case with no rounding + return false; + } + + // Values greater than or equal to 5 should round up, otherwise we round down. The IEEE + // 754 spec actually dictates that ties (exactly 5) should round to the nearest even number + // but that can have undesired behavior for custom numeric format strings. This probably + // needs further thought for .NET 5 so that we can be spec compliant and so that users + // can get the desired rounding behavior for their needs. + + return digit >= '5'; + } + } + + private static unsafe int FindSection(ReadOnlySpan format, int section) + { + int src; + char ch; + + if (section == 0) + return 0; + + fixed (char* pFormat = &MemoryMarshal.GetReference(format)) + { + src = 0; + while (true) + { + if (src >= format.Length) + { + return 0; + } + + switch (ch = pFormat[src++]) + { + case '\'': + case '"': + while (src < format.Length && pFormat[src] != 0 && pFormat[src++] != ch) ; + break; + case '\\': + if (src < format.Length && pFormat[src] != 0) + src++; + break; + case ';': + if (--section != 0) + break; + if (src < format.Length && pFormat[src] != 0 && pFormat[src] != ';') + return src; + goto case '\0'; + case '\0': + return 0; + } + } + } + } + + private static uint Low32(ulong value) => (uint)value; + + private static uint High32(ulong value) => (uint)((value & 0xFFFFFFFF00000000) >> 32); + + private static uint Int64DivMod1E9(ref ulong value) + { + uint rem = (uint)(value % 1000000000); + value /= 1000000000; + return rem; + } + + private static ulong ExtractFractionAndBiasedExponent(double value, out int exponent) + { + ulong bits = (ulong)(BitConverter.DoubleToInt64Bits(value)); + ulong fraction = (bits & 0xFFFFFFFFFFFFF); + exponent = ((int)(bits >> 52) & 0x7FF); + + if (exponent != 0) + { + // For normalized value, according to https://en.wikipedia.org/wiki/Double-precision_floating-point_format + // value = 1.fraction * 2^(exp - 1023) + // = (1 + mantissa / 2^52) * 2^(exp - 1023) + // = (2^52 + mantissa) * 2^(exp - 1023 - 52) + // + // So f = (2^52 + mantissa), e = exp - 1075; + + fraction |= (1UL << 52); + exponent -= 1075; + } + else + { + // For denormalized value, according to https://en.wikipedia.org/wiki/Double-precision_floating-point_format + // value = 0.fraction * 2^(1 - 1023) + // = (mantissa / 2^52) * 2^(-1022) + // = mantissa * 2^(-1022 - 52) + // = mantissa * 2^(-1074) + // So f = mantissa, e = -1074 + exponent = -1074; + } + + return fraction; + } + + private static uint ExtractFractionAndBiasedExponent(float value, out int exponent) + { + uint bits = (uint)(SingleToInt32Bits(value)); + uint fraction = (bits & 0x7FFFFF); + exponent = ((int)(bits >> 23) & 0xFF); + + if (exponent != 0) + { + // For normalized value, according to https://en.wikipedia.org/wiki/Single-precision_floating-point_format + // value = 1.fraction * 2^(exp - 127) + // = (1 + mantissa / 2^23) * 2^(exp - 127) + // = (2^23 + mantissa) * 2^(exp - 127 - 23) + // + // So f = (2^23 + mantissa), e = exp - 150; + + fraction |= (1U << 23); + exponent -= 150; + } + else + { + // For denormalized value, according to https://en.wikipedia.org/wiki/Single-precision_floating-point_format + // value = 0.fraction * 2^(1 - 127) + // = (mantissa / 2^23) * 2^(-126) + // = mantissa * 2^(-126 - 23) + // = mantissa * 2^(-149) + // So f = mantissa, e = -149 + exponent = -149; + } + + return fraction; + } + + static string FastAllocateString(int length) + { + return new string('\0', length); + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Grisu3.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Grisu3.cs new file mode 100644 index 00000000..49573aa2 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Grisu3.cs @@ -0,0 +1,1067 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System +{ + internal static partial class Number + { + // This is a port of the `Grisu3` implementation here: https://github.com/google/double-conversion/blob/a711666ddd063eb1e4b181a6cb981d39a1fc8bac/double-conversion/fast-dtoa.cc + // The backing algorithm and the proofs behind it are described in more detail here: http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf + // ======================================================================================================================================== + // + // Overview: + // + // The general idea behind Grisu3 is to leverage additional bits and cached powers of ten to generate the correct digits. + // The algorithm is imprecise for some numbers. Fortunately, the algorithm itself can determine this scenario and gives us + // a result indicating success or failure. We must fallback to a different algorithm for the failing scenario. + internal static class Grisu3 + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe bool IsNegative(double d) + { + return BitConverter.DoubleToInt64Bits(d) < 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe bool IsNegativeInfinity(float f) + { + return f == float.NegativeInfinity; + } + + private const int CachedPowersDecimalExponentDistance = 8; + private const int CachedPowersMinDecimalExponent = -348; + private const int CachedPowersPowerMaxDecimalExponent = 340; + private const int CachedPowersOffset = -CachedPowersMinDecimalExponent; + + // 1 / Log2(10) + private const double D1Log210 = 0.301029995663981195; + + // The minimal and maximal target exponents define the range of w's binary exponent, + // where w is the result of multiplying the input by a cached power of ten. + // + // A different range might be chosen on a different platform, to optimize digit generation, + // but a smaller range requires more powers of ten to be cached. + private const int MaximalTargetExponent = -32; + private const int MinimalTargetExponent = -60; + + private static readonly short[] s_CachedPowersBinaryExponent = new short[] + { + -1220, + -1193, + -1166, + -1140, + -1113, + -1087, + -1060, + -1034, + -1007, + -980, + -954, + -927, + -901, + -874, + -847, + -821, + -794, + -768, + -741, + -715, + -688, + -661, + -635, + -608, + -582, + -555, + -529, + -502, + -475, + -449, + -422, + -396, + -369, + -343, + -316, + -289, + -263, + -236, + -210, + -183, + -157, + -130, + -103, + -77, + -50, + -24, + 3, + 30, + 56, + 83, + 109, + 136, + 162, + 189, + 216, + 242, + 269, + 295, + 322, + 348, + 375, + 402, + 428, + 455, + 481, + 508, + 534, + 561, + 588, + 614, + 641, + 667, + 694, + 720, + 747, + 774, + 800, + 827, + 853, + 880, + 907, + 933, + 960, + 986, + 1013, + 1039, + 1066, + }; + + private static readonly short[] s_CachedPowersDecimalExponent = new short[] + { + CachedPowersMinDecimalExponent, + -340, + -332, + -324, + -316, + -308, + -300, + -292, + -284, + -276, + -268, + -260, + -252, + -244, + -236, + -228, + -220, + -212, + -204, + -196, + -188, + -180, + -172, + -164, + -156, + -148, + -140, + -132, + -124, + -116, + -108, + -100, + -92, + -84, + -76, + -68, + -60, + -52, + -44, + -36, + -28, + -20, + -12, + -4, + 4, + 12, + 20, + 28, + 36, + 44, + 52, + 60, + 68, + 76, + 84, + 92, + 100, + 108, + 116, + 124, + 132, + 140, + 148, + 156, + 164, + 172, + 180, + 188, + 196, + 204, + 212, + 220, + 228, + 236, + 244, + 252, + 260, + 268, + 276, + 284, + 292, + 300, + 308, + 316, + 324, + 332, + CachedPowersPowerMaxDecimalExponent, + }; + + private static readonly ulong[] s_CachedPowersSignificand = new ulong[] + { + 0xFA8FD5A0081C0288, + 0xBAAEE17FA23EBF76, + 0x8B16FB203055AC76, + 0xCF42894A5DCE35EA, + 0x9A6BB0AA55653B2D, + 0xE61ACF033D1A45DF, + 0xAB70FE17C79AC6CA, + 0xFF77B1FCBEBCDC4F, + 0xBE5691EF416BD60C, + 0x8DD01FAD907FFC3C, + 0xD3515C2831559A83, + 0x9D71AC8FADA6C9B5, + 0xEA9C227723EE8BCB, + 0xAECC49914078536D, + 0x823C12795DB6CE57, + 0xC21094364DFB5637, + 0x9096EA6F3848984F, + 0xD77485CB25823AC7, + 0xA086CFCD97BF97F4, + 0xEF340A98172AACE5, + 0xB23867FB2A35B28E, + 0x84C8D4DFD2C63F3B, + 0xC5DD44271AD3CDBA, + 0x936B9FCEBB25C996, + 0xDBAC6C247D62A584, + 0xA3AB66580D5FDAF6, + 0xF3E2F893DEC3F126, + 0xB5B5ADA8AAFF80B8, + 0x87625F056C7C4A8B, + 0xC9BCFF6034C13053, + 0x964E858C91BA2655, + 0xDFF9772470297EBD, + 0xA6DFBD9FB8E5B88F, + 0xF8A95FCF88747D94, + 0xB94470938FA89BCF, + 0x8A08F0F8BF0F156B, + 0xCDB02555653131B6, + 0x993FE2C6D07B7FAC, + 0xE45C10C42A2B3B06, + 0xAA242499697392D3, + 0xFD87B5F28300CA0E, + 0xBCE5086492111AEB, + 0x8CBCCC096F5088CC, + 0xD1B71758E219652C, + 0x9C40000000000000, + 0xE8D4A51000000000, + 0xAD78EBC5AC620000, + 0x813F3978F8940984, + 0xC097CE7BC90715B3, + 0x8F7E32CE7BEA5C70, + 0xD5D238A4ABE98068, + 0x9F4F2726179A2245, + 0xED63A231D4C4FB27, + 0xB0DE65388CC8ADA8, + 0x83C7088E1AAB65DB, + 0xC45D1DF942711D9A, + 0x924D692CA61BE758, + 0xDA01EE641A708DEA, + 0xA26DA3999AEF774A, + 0xF209787BB47D6B85, + 0xB454E4A179DD1877, + 0x865B86925B9BC5C2, + 0xC83553C5C8965D3D, + 0x952AB45CFA97A0B3, + 0xDE469FBD99A05FE3, + 0xA59BC234DB398C25, + 0xF6C69A72A3989F5C, + 0xB7DCBF5354E9BECE, + 0x88FCF317F22241E2, + 0xCC20CE9BD35C78A5, + 0x98165AF37B2153DF, + 0xE2A0B5DC971F303A, + 0xA8D9D1535CE3B396, + 0xFB9B7CD9A4A7443C, + 0xBB764C4CA7A44410, + 0x8BAB8EEFB6409C1A, + 0xD01FEF10A657842C, + 0x9B10A4E5E9913129, + 0xE7109BFBA19C0C9D, + 0xAC2820D9623BF429, + 0x80444B5E7AA7CF85, + 0xBF21E44003ACDD2D, + 0x8E679C2F5E44FF8F, + 0xD433179D9C8CB841, + 0x9E19DB92B4E31BA9, + 0xEB96BF6EBADF77D9, + 0xAF87023B9BF0EE6B, + }; + + private static readonly uint[] s_SmallPowersOfTen = new uint[] + { + 1, // 10^0 + 10, // 10^1 + 100, // 10^2 + 1000, // 10^3 + 10000, // 10^4 + 100000, // 10^5 + 1000000, // 10^6 + 10000000, // 10^7 + 100000000, // 10^8 + 1000000000, // 10^9 + }; + + public static bool TryRunDouble(double value, int requestedDigits, ref NumberBuffer number) + { + double v = IsNegative(value) ? -value : value; + + Debug.Assert(v > 0); + //Debug.Assert(double.IsFinite(v)); + + int length; + int decimalExponent; + bool result; + + if (requestedDigits == -1) + { + DiyFp w = DiyFp.CreateAndGetBoundaries(v, out DiyFp boundaryMinus, out DiyFp boundaryPlus).Normalize(); + result = TryRunShortest(in boundaryMinus, in w, in boundaryPlus, number.Digits, out length, out decimalExponent); + } + else + { + DiyFp w = new DiyFp(v).Normalize(); + result = TryRunCounted(in w, requestedDigits, number.Digits, out length, out decimalExponent); + } + + if (result) + { + Debug.Assert((requestedDigits == -1) || (length == requestedDigits)); + + number.Scale = length + decimalExponent; + number.Digits[length] = (byte)('\0'); + number.DigitsCount = length; + } + + return result; + } + + public static bool TryRunSingle(float value, int requestedDigits, ref NumberBuffer number) + { + float v = IsNegative(value) ? -value : value; + + Debug.Assert(v > 0); + //Debug.Assert(float.IsFinite(v)); + + int length; + int decimalExponent; + bool result; + + if (requestedDigits == -1) + { + DiyFp w = DiyFp.CreateAndGetBoundaries(v, out DiyFp boundaryMinus, out DiyFp boundaryPlus).Normalize(); + result = TryRunShortest(in boundaryMinus, in w, in boundaryPlus, number.Digits, out length, out decimalExponent); + } + else + { + DiyFp w = new DiyFp(v).Normalize(); + result = TryRunCounted(in w, requestedDigits, number.Digits, out length, out decimalExponent); + } + + if (result) + { + Debug.Assert((requestedDigits == -1) || (length == requestedDigits)); + + number.Scale = length + decimalExponent; + number.Digits[length] = (byte)('\0'); + number.DigitsCount = length; + } + + return result; + } + + // The counted version of Grisu3 only generates requestedDigits number of digits. + // This version does not generate the shortest representation, and with enough requested digits 0.1 will at some point print as 0.9999999... + // Grisu3 is too imprecise for real halfway cases (1.5 will not work) and therefore the rounding strategy for halfway cases is irrelevant. + private static bool TryRunCounted(in DiyFp w, int requestedDigits, Span buffer, out int length, out int decimalExponent) + { + Debug.Assert(requestedDigits > 0); + + int tenMkMinimalBinaryExponent = MinimalTargetExponent - (w.e + DiyFp.SignificandSize); + int tenMkMaximalBinaryExponent = MaximalTargetExponent - (w.e + DiyFp.SignificandSize); + + DiyFp tenMk = GetCachedPowerForBinaryExponentRange(tenMkMinimalBinaryExponent, tenMkMaximalBinaryExponent, out int mk); + + Debug.Assert(MinimalTargetExponent <= (w.e + tenMk.e + DiyFp.SignificandSize)); + Debug.Assert(MaximalTargetExponent >= (w.e + tenMk.e + DiyFp.SignificandSize)); + + // Note that tenMk is only an approximation of 10^-k. + // A DiyFp only contains a 64-bit significand and tenMk is thus only precise up to 64-bits. + + // The DiyFp.Multiply procedure rounds its result and tenMk is approximated too. + // The variable scaledW (as well as scaledBoundaryMinus/Plus) are now off by a small amount. + // + // In fact, scaledW - (w * 10^k) < 1ulp (unit in last place) of scaledW. + // In other words, let f = scaledW.f and e = scaledW.e, then: + // (f - 1) * 2^e < (w * 10^k) < (f + 1) * 2^e + + DiyFp scaledW = w.Multiply(in tenMk); + + // We now have (double)(scaledW * 10^-mk). + // + // DigitGenCounted will generate the first requestedDigits of scaledW and return together with a kappa such that: + // scaledW ~= buffer * 10^kappa. + // + // It will not always be exactly the same since DigitGenCounted only produces a limited number of digits. + + bool result = TryDigitGenCounted(in scaledW, requestedDigits, buffer, out length, out int kappa); + decimalExponent = -mk + kappa; + return result; + } + + // Provides a decimal representation of v. + // Returns true if it succeeds; otherwise, the result cannot be trusted. + // + // There will be length digits inside the buffer (not null-terminated). + // If the function returns true then: + // v == (double)(buffer * 10^decimalExponent) + // + // The digits in the buffer are the shortest represenation possible (no 0.09999999999999999 instead of 0.1). + // The shorter representation will even be chosen if the longer one would be closer to v. + // + // The last digit will be closest to the actual v. + // That is, even if several digits might correctly yield 'v' when read again, the closest will be computed. + private static bool TryRunShortest(in DiyFp boundaryMinus, in DiyFp w, in DiyFp boundaryPlus, Span buffer, out int length, out int decimalExponent) + { + // boundaryMinus and boundaryPlus are the boundaries between v and its closest floating-point neighbors. + // Any number strictly between boundaryMinus and boundaryPlus will round to v when converted to a double. + // Grisu3 will never output representations that lie exactly on a boundary. + + Debug.Assert(boundaryPlus.e == w.e); + + int tenMkMinimalBinaryExponent = MinimalTargetExponent - (w.e + DiyFp.SignificandSize); + int tenMkMaximalBinaryExponent = MaximalTargetExponent - (w.e + DiyFp.SignificandSize); + + DiyFp tenMk = GetCachedPowerForBinaryExponentRange(tenMkMinimalBinaryExponent, tenMkMaximalBinaryExponent, out int mk); + + Debug.Assert(MinimalTargetExponent <= (w.e + tenMk.e + DiyFp.SignificandSize)); + Debug.Assert(MaximalTargetExponent >= (w.e + tenMk.e + DiyFp.SignificandSize)); + + // Note that tenMk is only an approximation of 10^-k. + // A DiyFp only contains a 64-bit significan and tenMk is thus only precise up to 64-bits. + + // The DiyFp.Multiply procedure rounds its result and tenMk is approximated too. + // The variable scaledW (as well as scaledBoundaryMinus/Plus) are now off by a small amount. + // + // In fact, scaledW - (w * 10^k) < 1ulp (unit in last place) of scaledW. + // In other words, let f = scaledW.f and e = scaledW.e, then: + // (f - 1) * 2^e < (w * 10^k) < (f + 1) * 2^e + + DiyFp scaledW = w.Multiply(in tenMk); + Debug.Assert(scaledW.e == (boundaryPlus.e + tenMk.e + DiyFp.SignificandSize)); + + // In theory, it would be possible to avoid some recomputations by computing the difference between w + // and boundaryMinus/Plus (a power of 2) and to compute scaledBoundaryMinus/Plus by subtracting/adding + // from scaledW. However, the code becomes much less readable and the speed enhancements are not terrific. + + DiyFp scaledBoundaryMinus = boundaryMinus.Multiply(in tenMk); + DiyFp scaledBoundaryPlus = boundaryPlus.Multiply(in tenMk); + + // DigitGen will generate the digits of scaledW. Therefore, we have: + // v == (double)(scaledW * 10^-mk) + // + // Set decimalExponent == -mk and pass it to DigitGen and if scaledW is not an integer than it will be updated. + // For instance, if scaledW == 1.23 then the buffer will be filled with "123" and the decimalExponent will be decreased by 2. + + bool result = TryDigitGenShortest(in scaledBoundaryMinus, in scaledW, in scaledBoundaryPlus, buffer, out length, out int kappa); + decimalExponent = -mk + kappa; + return result; + } + + // Returns the biggest power of ten that is less than or equal to the given number. + // We furthermore receive the maximum number of bits 'number' has. + // + // Returns power == 10^(exponent) such that + // power <= number < power * 10 + // If numberBits == 0, then 0^(0-1) is returned. + // The number of bits must be <= 32. + // + // Preconditions: + // number < (1 << (numberBits + 1)) + private static uint BiggestPowerTen(uint number, int numberBits, out int exponentPlusOne) + { + // Inspired by the method for finding an integer log base 10 from here: + // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 + + Debug.Assert(number < (1U << (numberBits + 1))); + + // 1233/4096 is approximately 1/log2(10) + int exponentGuess = ((numberBits + 1) * 1233) >> 12; + Debug.Assert((uint)(exponentGuess) < s_SmallPowersOfTen.Length); + + uint power = s_SmallPowersOfTen[exponentGuess]; + + // We don't have any guarantees that 2^numberBits <= number + if (number < power) + { + exponentGuess--; + power = s_SmallPowersOfTen[exponentGuess]; + } + + exponentPlusOne = exponentGuess + 1; + return power; + } + + // Generates (at most) requestedDigits of input number w. + // + // w is a floating-point number (DiyFp), consisting of a significand and an exponent. + // Its exponent is bounded by MinimalTargetExponent and MaximalTargetExponent, hence: + // -60 <= w.e <= -32 + // + // Returns false if it fails, in which case the generated digits in the buffer should not be used. + // + // Preconditions: + // w is correct up to 1 ulp (unit in last place). That is, its error must be strictly less than a unit of its last digit. + // MinimalTargetExponent <= w.e <= MaximalTargetExponent + // + // Postconditions: + // Returns false if the procedure fails; otherwise: + // * buffer is not null-terminated, but length contains the number of digits. + // * The representation in buffer is the most precise representation of requestedDigits digits. + // * buffer contains at most requestedDigits digits of w. If there are less than requestedDigits digits then some trailing '0's have been removed. + // * kappa is such that w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2. + // + // This procedure takes into account the imprecision of its input numbers. + // If the precision is not enough to guarantee all the postconditions, then false is returned. + // This usually happens rarely, but the failure-rate increases with higher requestedDigits + private static bool TryDigitGenCounted(in DiyFp w, int requestedDigits, Span buffer, out int length, out int kappa) + { + Debug.Assert(MinimalTargetExponent <= w.e); + Debug.Assert(w.e <= MaximalTargetExponent); + Debug.Assert(MinimalTargetExponent >= -60); + Debug.Assert(MaximalTargetExponent <= -32); + + // w is assumed to have an error less than 1 unit. + // Whenever w is scaled we also scale its error. + ulong wError = 1; + + // We cut the input number into two parts: the integral digits and the fractional digits. + // We don't emit any decimal separator, but adapt kapp instead. + // For example: instead of writing "1.2", we put "12" into the buffer and increase kappa by 1. + var one = new DiyFp(1UL << -w.e, w.e); + + // Division by one is a shift. + uint integrals = (uint)(w.f >> -one.e); + + // Modulo by one is an and. + ulong fractionals = w.f & (one.f - 1); + + // We deviate from the original algorithm here and do some early checks to determine if we can satisfy requestedDigits. + // If we determine that we can't, we exit early and avoid most of the heavy lifting that the algorithm otherwise does. + // + // When fractionals is zero, we can easily determine if integrals can satisfy requested digits: + // If requestedDigits >= 11, integrals is not able to exhaust the count by itself since 10^(11 -1) > uint.MaxValue >= integrals. + // If integrals < 10^(requestedDigits - 1), integrals cannot exhaust the count. + // Otherwise, integrals might be able to exhaust the count and we need to execute the rest of the code. + if ((fractionals == 0) && ((requestedDigits >= 11) || (integrals < s_SmallPowersOfTen[requestedDigits - 1]))) + { + Debug.Assert(buffer[0] == '\0'); + length = 0; + kappa = 0; + return false; + } + + uint divisor = BiggestPowerTen(integrals, DiyFp.SignificandSize - (-one.e), out kappa); + length = 0; + + // Loop invariant: + // buffer = w / 10^kappa (integer division) + // These invariants hold for the first iteration: + // kappa has been initialized with the divisor exponent + 1 + // The divisor is the biggest power of ten that is smaller than integrals + while (kappa > 0) + { + uint digit = MathEx.DivRem(integrals, divisor, out integrals); + Debug.Assert(digit <= 9); + buffer[length] = (byte)('0' + digit); + + length++; + requestedDigits--; + kappa--; + + // Note that kappa now equals the exponent of the + // divisor and that the invariant thus holds again. + if (requestedDigits == 0) + { + break; + } + + divisor /= 10; + } + + if (requestedDigits == 0) + { + ulong rest = ((ulong)(integrals) << -one.e) + fractionals; + return TryRoundWeedCounted( + buffer, + length, + rest, + tenKappa: ((ulong)(divisor)) << -one.e, + unit: wError, + ref kappa + ); + } + + // The integrals have been generated and we are at the point of the decimal separator. + // In the following loop, we simply multiply the remaining digits by 10 and divide by one. + // We just need to pay attention to multiply associated data (the unit), too. + // Note that the multiplication by 10 does not overflow because: + // w.e >= -60 and thus one.e >= -60 + + Debug.Assert(one.e >= MinimalTargetExponent); + Debug.Assert(fractionals < one.f); + Debug.Assert((ulong.MaxValue / 10) >= one.f); + + while ((requestedDigits > 0) && (fractionals > wError)) + { + fractionals *= 10; + wError *= 10; + + // Integer division by one. + uint digit = (uint)(fractionals >> -one.e); + Debug.Assert(digit <= 9); + buffer[length] = (byte)('0' + digit); + + length++; + requestedDigits--; + kappa--; + + // Modulo by one. + fractionals &= (one.f - 1); + } + + if (requestedDigits != 0) + { + buffer[0] = (byte)('\0'); + length = 0; + kappa = 0; + return false; + } + + return TryRoundWeedCounted( + buffer, + length, + rest: fractionals, + tenKappa: one.f, + unit: wError, + ref kappa + ); + } + + // Generates the digits of input number w. + // + // w is a floating-point number (DiyFp), consisting of a significand and an exponent. + // Its exponent is bounded by kMinimalTargetExponent and kMaximalTargetExponent, hence: + // -60 <= w.e() <= -32. + // + // Returns false if it fails, in which case the generated digits in the buffer should not be used. + // + // Preconditions: + // low, w and high are correct up to 1 ulp (unit in the last place). That is, their error must be less than a unit of their last digits. + // low.e() == w.e() == high.e() + // low < w < high, and taking into account their error: low~ <= high~ + // kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent + // + // Postconditions: + // Returns false if procedure fails; otherwise: + // * buffer is not null-terminated, but len contains the number of digits. + // * buffer contains the shortest possible decimal digit-sequence such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the correct values of low and high (without their error). + // * If more than one decimal representation gives the minimal number of decimal digits then the one closest to W (where W is the correct value of w) is chosen. + // + // This procedure takes into account the imprecision of its input numbers. + // If the precision is not enough to guarantee all the postconditions then false is returned. + // This usually happens rarely (~0.5%). + // + // Say, for the sake of example, that: + // w.e() == -48, and w.f() == 0x1234567890abcdef + // + // w's value can be computed by w.f() * 2^w.e() + // + // We can obtain w's integral digits by simply shifting w.f() by -w.e(). + // -> w's integral part is 0x1234 + // w's fractional part is therefore 0x567890abcdef. + // + // Printing w's integral part is easy (simply print 0x1234 in decimal). + // + // In order to print its fraction we repeatedly multiply the fraction by 10 and get each digit. + // For example, the first digit after the point would be computed by + // (0x567890abcdef * 10) >> 48. -> 3 + // + // The whole thing becomes slightly more complicated because we want to stop once we have enough digits. + // That is, once the digits inside the buffer represent 'w' we can stop. + // + // Everything inside the interval low - high represents w. + // However we have to pay attention to low, high and w's imprecision. + private static bool TryDigitGenShortest(in DiyFp low, in DiyFp w, in DiyFp high, Span buffer, out int length, out int kappa) + { + Debug.Assert(low.e == w.e); + Debug.Assert(w.e == high.e); + + Debug.Assert((low.f + 1) <= (high.f - 1)); + + Debug.Assert(MinimalTargetExponent <= w.e); + Debug.Assert(w.e <= MaximalTargetExponent); + + // low, w, and high are imprecise, but by less than one ulp (unit in the last place). + // + // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that the new numbers + // are outside of the interval we want the final representation to lie in. + // + // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield numbers that + // are certain to lie in the interval. We will use this fact later on. + // + // We will now start by generating the digits within the uncertain interval. + // Later, we will weed out representations that lie outside the safe interval and thus might lie outside the correct interval. + + ulong unit = 1; + + var tooLow = new DiyFp(low.f - unit, low.e); + var tooHigh = new DiyFp(high.f + unit, high.e); + + // tooLow and tooHigh are guaranteed to lie outside the interval we want the generated number in. + + DiyFp unsafeInterval = tooHigh.Subtract(in tooLow); + + // We now cut the input number into two parts: the integral digits and the fractional digits. + // We will not write any decimal separator, but adapt kappa instead. + // + // Reminder: we are currently computing the digits (Stored inside the buffer) such that: + // tooLow < buffer * 10^kappa < tooHigh + // + // We use tooHigh for the digitGeneration and stop as soon as possible. + // If we stop early, we effectively round down. + + var one = new DiyFp(1UL << -w.e, w.e); + + // Division by one is a shift. + uint integrals = (uint)(tooHigh.f >> -one.e); + + // Modulo by one is an and. + ulong fractionals = tooHigh.f & (one.f - 1); + + uint divisor = BiggestPowerTen(integrals, DiyFp.SignificandSize - (-one.e), out kappa); + length = 0; + + // Loop invariant: + // buffer = tooHigh / 10^kappa (integer division) + // These invariants hold for the first iteration: + // kappa has been initialized with the divisor exponent + 1 + // The divisor is the biggest power of ten that is smaller than integrals + while (kappa > 0) + { + uint digit = MathEx.DivRem(integrals, divisor, out integrals); + Debug.Assert(digit <= 9); + buffer[length] = (byte)('0' + digit); + + length++; + kappa--; + + // Note that kappa now equals the exponent of the + // divisor and that the invariant thus holds again. + + ulong rest = ((ulong)(integrals) << -one.e) + fractionals; + + // Invariant: tooHigh = buffer * 10^kappa + DiyFp(rest, one.e) + // Reminder: unsafeInterval.e == one.e + + if (rest < unsafeInterval.f) + { + // Rounding down (by not emitting the remaining digits) + // yields a number that lies within the unsafe interval + + return TryRoundWeedShortest( + buffer, + length, + tooHigh.Subtract(w).f, + unsafeInterval.f, + rest, + tenKappa: ((ulong)(divisor)) << -one.e, + unit + ); + } + + divisor /= 10; + } + + // The integrals have been generated and we are at the point of the decimal separator. + // In the following loop, we simply multiply the remaining digits by 10 and divide by one. + // We just need to pay attention to multiply associated data (the unit), too. + // Note that the multiplication by 10 does not overflow because: + // w.e >= -60 and thus one.e >= -60 + + Debug.Assert(one.e >= MinimalTargetExponent); + Debug.Assert(fractionals < one.f); + Debug.Assert((ulong.MaxValue / 10) >= one.f); + + while (true) + { + fractionals *= 10; + unit *= 10; + + unsafeInterval = new DiyFp(unsafeInterval.f * 10, unsafeInterval.e); + + // Integer division by one. + uint digit = (uint)(fractionals >> -one.e); + Debug.Assert(digit <= 9); + buffer[length] = (byte)('0' + digit); + + length++; + kappa--; + + // Modulo by one. + fractionals &= (one.f - 1); + + if (fractionals < unsafeInterval.f) + { + return TryRoundWeedShortest( + buffer, + length, + tooHigh.Subtract(w).f * unit, + unsafeInterval.f, + rest: fractionals, + tenKappa: one.f, + unit + ); + } + } + } + + // Returns a cached power-of-ten with a binary exponent in the range [minExponent; maxExponent] (boundaries included). + private static DiyFp GetCachedPowerForBinaryExponentRange(int minExponent, int maxExponent, out int decimalExponent) + { + Debug.Assert(s_CachedPowersSignificand.Length == s_CachedPowersBinaryExponent.Length); + Debug.Assert(s_CachedPowersSignificand.Length == s_CachedPowersDecimalExponent.Length); + + double k = Math.Ceiling((minExponent + DiyFp.SignificandSize - 1) * D1Log210); + int index = ((CachedPowersOffset + (int)(k) - 1) / CachedPowersDecimalExponentDistance) + 1; + + Debug.Assert((uint)(index) < s_CachedPowersSignificand.Length); + + Debug.Assert(minExponent <= s_CachedPowersBinaryExponent[index]); + Debug.Assert(s_CachedPowersBinaryExponent[index] <= maxExponent); + + decimalExponent = s_CachedPowersDecimalExponent[index]; + return new DiyFp(s_CachedPowersSignificand[index], s_CachedPowersBinaryExponent[index]); + } + + // Rounds the buffer upwards if the result is closer to v by possibly adding 1 to the buffer. + // If the precision of the calculation is not sufficient to round correctly, return false. + // + // The rounding might shift the whole buffer, in which case, the kappy is adjusted. + // For example "99", kappa = 3 might become "10", kappa = 4. + // + // If (2 * rest) > tenKappa then the buffer needs to be round up. + // rest can have an error of +/- 1 unit. + // This function accounts for the imprecision and returns false if the rounding direction cannot be unambiguously determined. + // + // Preconditions: + // rest < tenKappa + private static bool TryRoundWeedCounted(Span buffer, int length, ulong rest, ulong tenKappa, ulong unit, ref int kappa) + { + Debug.Assert(rest < tenKappa); + + // The following tests are done in a specific order to avoid overflows. + // They will work correctly with any ulong values of rest < tenKappa and unit. + // + // If the unit is too big, then we don't know which way to round. + // For example, a unit of 50 means that the real number lies within rest +/- 50. + // If 10^kappa == 40, then there is no way to tell which way to round. + // + // Even if unit is just half the size of 10^kappa we are already completely lost. + // And after the previous test, we know that the expression will not over/underflow. + if ((unit >= tenKappa) || ((tenKappa - unit) <= unit)) + { + return false; + } + + // If 2 * (rest + unit) <= 10^kappa, we can safely round down. + if (((tenKappa - rest) > rest) && ((tenKappa - (2 * rest)) >= (2 * unit))) + { + return true; + } + + // If 2 * (rest - unit) >= 10^kappa, we can safely round up. + if ((rest > unit) && (tenKappa <= (rest - unit) || ((tenKappa - (rest - unit)) <= (rest - unit)))) + { + // Increment the last digit recursively until we find a non '9' digit. + buffer[length - 1]++; + + for (int i = (length - 1); i > 0; i--) + { + if (buffer[i] != ('0' + 10)) + { + break; + } + + buffer[i] = (byte)('0'); + buffer[i - 1]++; + } + + // If the first digit is now '0'+10, we had a buffer with all '9's. + // With the exception of the first digit, all digits are now '0'. + // Simply switch the first digit to '1' and adjust the kappa. + // For example, "99" becomes "10" and the power (the kappa) is increased. + if (buffer[0] == ('0' + 10)) + { + buffer[0] = (byte)('1'); + kappa++; + } + + return true; + } + + return false; + } + + // Adjusts the last digit of the generated number and screens out generated solutions that may be inaccurate. + // A solution may be inaccurate if it is outside the safe interval or if we cannot provide that it is closer to the input than a neighboring representation of the same length. + // + // Input: + // buffer containing the digits of tooHigh / 10^kappa + // the buffer's length + // distanceTooHighW == (tooHigh - w).f * unit + // unsafeInterval == (tooHigh - tooLow).f * unit + // rest = (tooHigh - buffer * 10^kapp).f * unit + // tenKappa = 10^kappa * unit + // unit = the common multiplier + // + // Output: + // Returns true if the buffer is guaranteed to contain the closest representable number to the input. + // + // Modifies the generated digits in the buffer to approach (round towards) w. + private static bool TryRoundWeedShortest(Span buffer, int length, ulong distanceTooHighW, ulong unsafeInterval, ulong rest, ulong tenKappa, ulong unit) + { + ulong smallDistance = distanceTooHighW - unit; + ulong bigDistance = distanceTooHighW + unit; + + // Let wLow = tooHigh - bigDistance, and wHigh = tooHigh - smallDistance. + // + // Note: wLow < w < wHigh + // + // The real w * unit must lie somewhere inside the interval + // ]w_low; w_high[ (often written as "(w_low; w_high)") + + // Basically the buffer currently contains a number in the unsafe interval + // ]too_low; too_high[ with too_low < w < too_high + // + // tooHigh - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ^v 1 unit ^ ^ ^ ^ + // boundaryHigh --------------------- . . . . + // ^v 1 unit . . . . + // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . + // . . ^ . . + // . bigDistance . . . + // . . . . rest + // smallDistance . . . . + // v . . . . + // wHigh - - - - - - - - - - - - - - - - - - . . . . + // ^v 1 unit . . . . + // w --------------------------------------- . . . . + // ^v 1 unit v . . . + // wLow - - - - - - - - - - - - - - - - - - - - - . . . + // . . v + // buffer -------------------------------------------------+-------+-------- + // . . + // safeInterval . + // v . + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . + // ^v 1 unit . + // boundaryLow ------------------------- unsafeInterval + // ^v 1 unit v + // tooLow - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // + // Note that the value of buffer could lie anywhere inside the range tooLow to tooHigh. + // + // boundaryLow, boundaryHigh and w are approximations of the real boundaries and v (the input number). + // They are guaranteed to be precise up to one unit. + // In fact the error is guaranteed to be strictly less than one unit. + // + // Anything that lies outside the unsafe interval is guaranteed not to round to v when read again. + // Anything that lies inside the safe interval is guaranteed to round to v when read again. + // + // If the number inside the buffer lies inside the unsafe interval but not inside the safe interval + // then we simply do not know and bail out (returning false). + // + // Similarly we have to take into account the imprecision of 'w' when finding the closest representation of 'w'. + // If we have two potential representations, and one is closer to both wLow and wHigh, then we know it is closer to the actual value v. + // + // By generating the digits of tooHigh we got the largest (closest to tooHigh) buffer that is still in the unsafe interval. + // In the case where wHigh < buffer < tooHigh we try to decrement the buffer. + // This way the buffer approaches (rounds towards) w. + // + // There are 3 conditions that stop the decrementation process: + // 1) the buffer is already below wHigh + // 2) decrementing the buffer would make it leave the unsafe interval + // 3) decrementing the buffer would yield a number below wHigh and farther away than the current number. + // + // In other words: + // (buffer{-1} < wHigh) && wHigh - buffer{-1} > buffer - wHigh + // + // Instead of using the buffer directly we use its distance to tooHigh. + // + // Conceptually rest ~= tooHigh - buffer + // + // We need to do the following tests in this order to avoid over- and underflows. + + Debug.Assert(rest <= unsafeInterval); + + while ((rest < smallDistance) && ((unsafeInterval - rest) >= tenKappa) && (((rest + tenKappa) < smallDistance) || ((smallDistance - rest) >= (rest + tenKappa - smallDistance)))) + { + buffer[length - 1]--; + rest += tenKappa; + } + + // We have approached w+ as much as possible. + // We now test if approaching w- would require changing the buffer. + // If yes, then we have two possible representations close to w, but we cannot decide which one is closer. + if ((rest < bigDistance) && ((unsafeInterval - rest) >= tenKappa) && (((rest + tenKappa) < bigDistance) || ((bigDistance - rest) > (rest + tenKappa - bigDistance)))) + { + return false; + } + + // Weeding test. + // + // The safe interval is [tooLow + 2 ulp; tooHigh - 2 ulp] + // Since tooLow = tooHigh - unsafeInterval this is equivalent to + // [tooHigh - unsafeInterval + 4 ulp; tooHigh - 2 ulp] + // + // Conceptually we have: rest ~= tooHigh - buffer + return ((2 * unit) <= rest) && (rest <= (unsafeInterval - 4 * unit)); + } + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberBuffer.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberBuffer.cs new file mode 100644 index 00000000..b9350468 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberBuffer.cs @@ -0,0 +1,124 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Text; + +namespace System +{ + internal static partial class Number + { + // We need 1 additional byte, per length, for the terminating null + internal const int DecimalNumberBufferLength = 29 + 1 + 1; // 29 for the longest input + 1 for rounding + internal const int DoubleNumberBufferLength = 767 + 1 + 1; // 767 for the longest input + 1 for rounding: 4.9406564584124654E-324 + internal const int Int32NumberBufferLength = 10 + 1; // 10 for the longest input: 2,147,483,647 + internal const int Int64NumberBufferLength = 19 + 1; // 19 for the longest input: 9,223,372,036,854,775,807 + internal const int SingleNumberBufferLength = 112 + 1 + 1; // 112 for the longest input + 1 for rounding: 1.40129846E-45 + internal const int UInt32NumberBufferLength = 10 + 1; // 10 for the longest input: 4,294,967,295 + internal const int UInt64NumberBufferLength = 20 + 1; // 20 for the longest input: 18,446,744,073,709,551,615 + + internal unsafe ref struct NumberBuffer + { + public int DigitsCount; + public int Scale; + public bool IsNegative; + public bool HasNonZeroTail; + public NumberBufferKind Kind; + public Span Digits; + + public NumberBuffer(NumberBufferKind kind, byte* digits, int digitsLength) + { + Debug.Assert(digits != null); + Debug.Assert(digitsLength > 0); + + DigitsCount = 0; + Scale = 0; + IsNegative = false; + HasNonZeroTail = false; + Kind = kind; + Digits = new Span(digits, digitsLength); + +#if DEBUG + Digits.Fill(0xCC); +#endif + + Digits[0] = (byte)('\0'); + CheckConsistency(); + } + + [Conditional("DEBUG")] + public void CheckConsistency() + { +#if DEBUG + Debug.Assert((Kind == NumberBufferKind.Integer) || (Kind == NumberBufferKind.Decimal) || (Kind == NumberBufferKind.FloatingPoint)); + Debug.Assert(Digits[0] != '0', "Leading zeros should never be stored in a Number"); + + int numDigits; + for (numDigits = 0; numDigits < Digits.Length; numDigits++) + { + byte digit = Digits[numDigits]; + + if (digit == 0) + { + break; + } + + Debug.Assert((digit >= '0') && (digit <= '9'), "Unexpected character found in Number"); + } + + Debug.Assert(numDigits == DigitsCount, "Null terminator found in unexpected location in Number"); + Debug.Assert(numDigits < Digits.Length, "Null terminator not found in Number"); +#endif // DEBUG + } + + public byte* GetDigitsPointer() + { + // This is safe to do since we are a ref struct + return (byte*)(Unsafe.AsPointer(ref Digits[0])); + } + + // + // Code coverage note: This only exists so that Number displays nicely in the VS watch window. So yes, I know it works. + // + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + + sb.Append('['); + sb.Append('"'); + + for (int i = 0; i < Digits.Length; i++) + { + byte digit = Digits[i]; + + if (digit == 0) + { + break; + } + + sb.Append((char)(digit)); + } + + sb.Append('"'); + sb.Append(", Length = ").Append(DigitsCount); + sb.Append(", Scale = ").Append(Scale); + sb.Append(", IsNegative = ").Append(IsNegative); + sb.Append(", HasNonZeroTail = ").Append(HasNonZeroTail); + sb.Append(", Kind = ").Append(Kind); + sb.Append(']'); + + return sb.ToString(); + } + } + + internal enum NumberBufferKind : byte + { + Unknown = 0, + Integer = 1, + Decimal = 2, + FloatingPoint = 3, + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberToFloatingPointBits.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberToFloatingPointBits.cs new file mode 100644 index 00000000..d0bf894c --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberToFloatingPointBits.cs @@ -0,0 +1,637 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System +{ + internal unsafe partial class Number + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe int SingleToInt32Bits(float value) + { + return *((int*)&value); + } + + public readonly struct FloatingPointInfo + { + public static readonly FloatingPointInfo Double = new FloatingPointInfo( + denormalMantissaBits: 52, + exponentBits: 11, + maxBinaryExponent: 1023, + exponentBias: 1023, + infinityBits: 0x7FF00000_00000000 + ); + + public static readonly FloatingPointInfo Single = new FloatingPointInfo( + denormalMantissaBits: 23, + exponentBits: 8, + maxBinaryExponent: 127, + exponentBias: 127, + infinityBits: 0x7F800000 + ); + + public ulong ZeroBits { get; } + public ulong InfinityBits { get; } + + public ulong NormalMantissaMask { get; } + public ulong DenormalMantissaMask { get; } + + public int MinBinaryExponent { get; } + public int MaxBinaryExponent { get; } + + public int ExponentBias { get; } + public int OverflowDecimalExponent { get; } + + public ushort NormalMantissaBits { get; } + public ushort DenormalMantissaBits { get; } + + public ushort ExponentBits { get; } + + public FloatingPointInfo(ushort denormalMantissaBits, ushort exponentBits, int maxBinaryExponent, int exponentBias, ulong infinityBits) + { + ExponentBits = exponentBits; + + DenormalMantissaBits = denormalMantissaBits; + NormalMantissaBits = (ushort)(denormalMantissaBits + 1); // we get an extra (hidden) bit for normal mantissas + + OverflowDecimalExponent = (maxBinaryExponent + 2 * NormalMantissaBits) / 3; + ExponentBias = exponentBias; + + MaxBinaryExponent = maxBinaryExponent; + MinBinaryExponent = 1 - maxBinaryExponent; + + DenormalMantissaMask = (1UL << denormalMantissaBits) - 1; + NormalMantissaMask = (1UL << NormalMantissaBits) - 1; + + InfinityBits = infinityBits; + ZeroBits = 0; + } + } + + private static readonly float[] s_Pow10SingleTable = new float[] + { + 1e0f, // 10^0 + 1e1f, // 10^1 + 1e2f, // 10^2 + 1e3f, // 10^3 + 1e4f, // 10^4 + 1e5f, // 10^5 + 1e6f, // 10^6 + 1e7f, // 10^7 + 1e8f, // 10^8 + 1e9f, // 10^9 + 1e10f, // 10^10 + }; + + private static readonly double[] s_Pow10DoubleTable = new double[] + { + 1e0, // 10^0 + 1e1, // 10^1 + 1e2, // 10^2 + 1e3, // 10^3 + 1e4, // 10^4 + 1e5, // 10^5 + 1e6, // 10^6 + 1e7, // 10^7 + 1e8, // 10^8 + 1e9, // 10^9 + 1e10, // 10^10 + 1e11, // 10^11 + 1e12, // 10^12 + 1e13, // 10^13 + 1e14, // 10^14 + 1e15, // 10^15 + 1e16, // 10^16 + 1e17, // 10^17 + 1e18, // 10^18 + 1e19, // 10^19 + 1e20, // 10^20 + 1e21, // 10^21 + 1e22, // 10^22 + }; + + private static void AccumulateDecimalDigitsIntoBigInteger(ref NumberBuffer number, uint firstIndex, uint lastIndex, out BigInteger result) + { + BigInteger.SetZero(out result); + + byte* src = number.GetDigitsPointer() + firstIndex; + uint remaining = lastIndex - firstIndex; + + while (remaining != 0) + { + uint count = Math.Min(remaining, 9); + uint value = DigitsToUInt32(src, (int)(count)); + + result.MultiplyPow10(count); + result.Add(value); + + src += count; + remaining -= count; + } + } + + private static ulong AssembleFloatingPointBits(in FloatingPointInfo info, ulong initialMantissa, int initialExponent, bool hasZeroTail) + { + // number of bits by which we must adjust the mantissa to shift it into the + // correct position, and compute the resulting base two exponent for the + // normalized mantissa: + uint initialMantissaBits = BigInteger.CountSignificantBits(initialMantissa); + int normalMantissaShift = info.NormalMantissaBits - (int)(initialMantissaBits); + int normalExponent = initialExponent - normalMantissaShift; + + ulong mantissa = initialMantissa; + int exponent = normalExponent; + + if (normalExponent > info.MaxBinaryExponent) + { + // The exponent is too large to be represented by the floating point + // type; report the overflow condition: + return info.InfinityBits; + } + else if (normalExponent < info.MinBinaryExponent) + { + // The exponent is too small to be represented by the floating point + // type as a normal value, but it may be representable as a denormal + // value. Compute the number of bits by which we need to shift the + // mantissa in order to form a denormal number. (The subtraction of + // an extra 1 is to account for the hidden bit of the mantissa that + // is not available for use when representing a denormal.) + int denormalMantissaShift = normalMantissaShift + normalExponent + info.ExponentBias - 1; + + // Denormal values have an exponent of zero, so the debiased exponent is + // the negation of the exponent bias: + exponent = -info.ExponentBias; + + if (denormalMantissaShift < 0) + { + // Use two steps for right shifts: for a shift of N bits, we first + // shift by N-1 bits, then shift the last bit and use its value to + // round the mantissa. + mantissa = RightShiftWithRounding(mantissa, -denormalMantissaShift, hasZeroTail); + + // If the mantissa is now zero, we have underflowed: + if (mantissa == 0) + { + return info.ZeroBits; + } + + // When we round the mantissa, the result may be so large that the + // number becomes a normal value. For example, consider the single + // precision case where the mantissa is 0x01ffffff and a right shift + // of 2 is required to shift the value into position. We perform the + // shift in two steps: we shift by one bit, then we shift again and + // round using the dropped bit. The initial shift yields 0x00ffffff. + // The rounding shift then yields 0x007fffff and because the least + // significant bit was 1, we add 1 to this number to round it. The + // final result is 0x00800000. + // + // 0x00800000 is 24 bits, which is more than the 23 bits available + // in the mantissa. Thus, we have rounded our denormal number into + // a normal number. + // + // We detect this case here and re-adjust the mantissa and exponent + // appropriately, to form a normal number: + if (mantissa > info.DenormalMantissaMask) + { + // We add one to the denormal_mantissa_shift to account for the + // hidden mantissa bit (we subtracted one to account for this bit + // when we computed the denormal_mantissa_shift above). + exponent = initialExponent - (denormalMantissaShift + 1) - normalMantissaShift; + } + } + else + { + mantissa <<= denormalMantissaShift; + } + } + else + { + if (normalMantissaShift < 0) + { + // Use two steps for right shifts: for a shift of N bits, we first + // shift by N-1 bits, then shift the last bit and use its value to + // round the mantissa. + mantissa = RightShiftWithRounding(mantissa, -normalMantissaShift, hasZeroTail); + + // When we round the mantissa, it may produce a result that is too + // large. In this case, we divide the mantissa by two and increment + // the exponent (this does not change the value). + if (mantissa > info.NormalMantissaMask) + { + mantissa >>= 1; + exponent++; + + // The increment of the exponent may have generated a value too + // large to be represented. In this case, report the overflow: + if (exponent > info.MaxBinaryExponent) + { + return info.InfinityBits; + } + } + } + else if (normalMantissaShift > 0) + { + mantissa <<= normalMantissaShift; + } + } + + // Unset the hidden bit in the mantissa and assemble the floating point value + // from the computed components: + mantissa &= info.DenormalMantissaMask; + + Debug.Assert((info.DenormalMantissaMask & (1UL << info.DenormalMantissaBits)) == 0); + ulong shiftedExponent = ((ulong)(exponent + info.ExponentBias)) << info.DenormalMantissaBits; + Debug.Assert((shiftedExponent & info.DenormalMantissaMask) == 0); + Debug.Assert((mantissa & ~info.DenormalMantissaMask) == 0); + Debug.Assert((shiftedExponent & ~(((1UL << info.ExponentBits) - 1) << info.DenormalMantissaBits)) == 0); // exponent fits in its place + + return shiftedExponent | mantissa; + } + + private static ulong ConvertBigIntegerToFloatingPointBits(ref BigInteger value, in FloatingPointInfo info, uint integerBitsOfPrecision, bool hasNonZeroFractionalPart) + { + int baseExponent = info.DenormalMantissaBits; + + // When we have 64-bits or less of precision, we can just get the mantissa directly + if (integerBitsOfPrecision <= 64) + { + return AssembleFloatingPointBits(in info, value.ToUInt64(), baseExponent, !hasNonZeroFractionalPart); + } + + uint topBlockIndex = MathEx.DivRem(integerBitsOfPrecision, 32, out uint topBlockBits); + uint middleBlockIndex = topBlockIndex - 1; + uint bottomBlockIndex = middleBlockIndex - 1; + + ulong mantissa; + int exponent = baseExponent + ((int)(bottomBlockIndex) * 32); + bool hasZeroTail = !hasNonZeroFractionalPart; + + // When the top 64-bits perfectly span two blocks, we can get those blocks directly + if (topBlockBits == 0) + { + mantissa = ((ulong)(value.GetBlock(middleBlockIndex)) << 32) + value.GetBlock(bottomBlockIndex); + } + else + { + // Otherwise, we need to read three blocks and combine them into a 64-bit mantissa + + int bottomBlockShift = (int)(topBlockBits); + int topBlockShift = 64 - bottomBlockShift; + int middleBlockShift = topBlockShift - 32; + + exponent += (int)(topBlockBits); + + uint bottomBlock = value.GetBlock(bottomBlockIndex); + uint bottomBits = bottomBlock >> bottomBlockShift; + + ulong middleBits = (ulong)(value.GetBlock(middleBlockIndex)) << middleBlockShift; + ulong topBits = (ulong)(value.GetBlock(topBlockIndex)) << topBlockShift; + + mantissa = topBits + middleBits + bottomBits; + + uint unusedBottomBlockBitsMask = (1u << (int)(topBlockBits)) - 1; + hasZeroTail &= (bottomBlock & unusedBottomBlockBitsMask) == 0; + } + + for (uint i = 0; i != bottomBlockIndex; i++) + { + hasZeroTail &= (value.GetBlock(i) == 0); + } + + return AssembleFloatingPointBits(in info, mantissa, exponent, hasZeroTail); + } + + // get 32-bit integer from at most 9 digits + private static uint DigitsToUInt32(byte* p, int count) + { + Debug.Assert((1 <= count) && (count <= 9)); + + byte* end = (p + count); + uint res = (uint)(p[0] - '0'); + + for (p++; p < end; p++) + { + res = (10 * res) + p[0] - '0'; + } + + return res; + } + + // get 64-bit integer from at most 19 digits + private static ulong DigitsToUInt64(byte* p, int count) + { + Debug.Assert((1 <= count) && (count <= 19)); + + byte* end = (p + count); + ulong res = (ulong)(p[0] - '0'); + + for (p++; p < end; p++) + { + res = (10 * res) + p[0] - '0'; + } + + return res; + } + + private static ulong NumberToFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info) + { + Debug.Assert(number.GetDigitsPointer()[0] != '0'); + + Debug.Assert(number.Scale <= FloatingPointMaxExponent); + Debug.Assert(number.Scale >= FloatingPointMinExponent); + + Debug.Assert(number.DigitsCount != 0); + + // The input is of the form 0.Mantissa x 10^Exponent, where 'Mantissa' are + // the decimal digits of the mantissa and 'Exponent' is the decimal exponent. + // We decompose the mantissa into two parts: an integer part and a fractional + // part. If the exponent is positive, then the integer part consists of the + // first 'exponent' digits, or all present digits if there are fewer digits. + // If the exponent is zero or negative, then the integer part is empty. In + // either case, the remaining digits form the fractional part of the mantissa. + + uint totalDigits = (uint)(number.DigitsCount); + uint positiveExponent = (uint)(Math.Max(0, number.Scale)); + + uint integerDigitsPresent = Math.Min(positiveExponent, totalDigits); + uint fractionalDigitsPresent = totalDigits - integerDigitsPresent; + + uint fastExponent = (uint)(Math.Abs(number.Scale - integerDigitsPresent - fractionalDigitsPresent)); + + // When the number of significant digits is less than or equal to 15 and the + // scale is less than or equal to 22, we can take some shortcuts and just rely + // on floating-point arithmetic to compute the correct result. This is + // because each floating-point precision values allows us to exactly represent + // different whole integers and certain powers of 10, depending on the underlying + // formats exact range. Additionally, IEEE operations dictate that the result is + // computed to the infinitely precise result and then rounded, which means that + // we can rely on it to produce the correct result when both inputs are exact. + + byte* src = number.GetDigitsPointer(); + + if ((info.DenormalMantissaBits == 23) && (totalDigits <= 7) && (fastExponent <= 10)) + { + // It is only valid to do this optimization for single-precision floating-point + // values since we can lose some of the mantissa bits and would return the + // wrong value when upcasting to double. + + float result = DigitsToUInt32(src, (int)(totalDigits)); + float scale = s_Pow10SingleTable[fastExponent]; + + if (fractionalDigitsPresent != 0) + { + result /= scale; + } + else + { + result *= scale; + } + + return (uint)(SingleToInt32Bits(result)); + } + + if ((totalDigits <= 15) && (fastExponent <= 22)) + { + double result = DigitsToUInt64(src, (int)(totalDigits)); + double scale = s_Pow10DoubleTable[fastExponent]; + + if (fractionalDigitsPresent != 0) + { + result /= scale; + } + else + { + result *= scale; + } + + if (info.DenormalMantissaBits == 52) + { + return (ulong)(BitConverter.DoubleToInt64Bits(result)); + } + else + { + Debug.Assert(info.DenormalMantissaBits == 23); + return (uint)(SingleToInt32Bits((float)(result))); + } + } + + return NumberToFloatingPointBitsSlow(ref number, in info, positiveExponent, integerDigitsPresent, fractionalDigitsPresent); + } + + private static ulong NumberToFloatingPointBitsSlow(ref NumberBuffer number, in FloatingPointInfo info, uint positiveExponent, uint integerDigitsPresent, uint fractionalDigitsPresent) + { + // To generate an N bit mantissa we require N + 1 bits of precision. The + // extra bit is used to correctly round the mantissa (if there are fewer bits + // than this available, then that's totally okay; in that case we use what we + // have and we don't need to round). + uint requiredBitsOfPrecision = (uint)(info.NormalMantissaBits + 1); + + uint totalDigits = (uint)(number.DigitsCount); + uint integerDigitsMissing = positiveExponent - integerDigitsPresent; + + const uint IntegerFirstIndex = 0; + uint integerLastIndex = integerDigitsPresent; + + uint fractionalFirstIndex = integerLastIndex; + uint fractionalLastIndex = totalDigits; + + // First, we accumulate the integer part of the mantissa into a big_integer: + AccumulateDecimalDigitsIntoBigInteger(ref number, IntegerFirstIndex, integerLastIndex, out BigInteger integerValue); + + if (integerDigitsMissing > 0) + { + if (integerDigitsMissing > info.OverflowDecimalExponent) + { + return info.InfinityBits; + } + + integerValue.MultiplyPow10(integerDigitsMissing); + } + + // At this point, the integer_value contains the value of the integer part + // of the mantissa. If either [1] this number has more than the required + // number of bits of precision or [2] the mantissa has no fractional part, + // then we can assemble the result immediately: + uint integerBitsOfPrecision = BigInteger.CountSignificantBits(ref integerValue); + + if ((integerBitsOfPrecision >= requiredBitsOfPrecision) || (fractionalDigitsPresent == 0)) + { + return ConvertBigIntegerToFloatingPointBits( + ref integerValue, + in info, + integerBitsOfPrecision, + fractionalDigitsPresent != 0 + ); + } + + // Otherwise, we did not get enough bits of precision from the integer part, + // and the mantissa has a fractional part. We parse the fractional part of + // the mantissa to obtain more bits of precision. To do this, we convert + // the fractional part into an actual fraction N/M, where the numerator N is + // computed from the digits of the fractional part, and the denominator M is + // computed as the power of 10 such that N/M is equal to the value of the + // fractional part of the mantissa. + + uint fractionalDenominatorExponent = fractionalDigitsPresent; + + if (number.Scale < 0) + { + fractionalDenominatorExponent += (uint)(-number.Scale); + } + + if ((integerBitsOfPrecision == 0) && (fractionalDenominatorExponent - (int)(totalDigits)) > info.OverflowDecimalExponent) + { + // If there were any digits in the integer part, it is impossible to + // underflow (because the exponent cannot possibly be small enough), + // so if we underflow here it is a true underflow and we return zero. + return info.ZeroBits; + } + + AccumulateDecimalDigitsIntoBigInteger(ref number, fractionalFirstIndex, fractionalLastIndex, out BigInteger fractionalNumerator); + + if (fractionalNumerator.IsZero()) + { + return ConvertBigIntegerToFloatingPointBits( + ref integerValue, + in info, + integerBitsOfPrecision, + fractionalDigitsPresent != 0 + ); + } + + BigInteger.Pow10(fractionalDenominatorExponent, out BigInteger fractionalDenominator); + + // Because we are using only the fractional part of the mantissa here, the + // numerator is guaranteed to be smaller than the denominator. We normalize + // the fraction such that the most significant bit of the numerator is in + // the same position as the most significant bit in the denominator. This + // ensures that when we later shift the numerator N bits to the left, we + // will produce N bits of precision. + uint fractionalNumeratorBits = BigInteger.CountSignificantBits(ref fractionalNumerator); + uint fractionalDenominatorBits = BigInteger.CountSignificantBits(ref fractionalDenominator); + + uint fractionalShift = 0; + + if (fractionalDenominatorBits > fractionalNumeratorBits) + { + fractionalShift = fractionalDenominatorBits - fractionalNumeratorBits; + } + + if (fractionalShift > 0) + { + fractionalNumerator.ShiftLeft(fractionalShift); + } + + uint requiredFractionalBitsOfPrecision = requiredBitsOfPrecision - integerBitsOfPrecision; + uint remainingBitsOfPrecisionRequired = requiredFractionalBitsOfPrecision; + + if (integerBitsOfPrecision > 0) + { + // If the fractional part of the mantissa provides no bits of precision + // and cannot affect rounding, we can just take whatever bits we got from + // the integer part of the mantissa. This is the case for numbers like + // 5.0000000000000000000001, where the significant digits of the fractional + // part start so far to the right that they do not affect the floating + // point representation. + // + // If the fractional shift is exactly equal to the number of bits of + // precision that we require, then no fractional bits will be part of the + // result, but the result may affect rounding. This is e.g. the case for + // large, odd integers with a fractional part greater than or equal to .5. + // Thus, we need to do the division to correctly round the result. + if (fractionalShift > remainingBitsOfPrecisionRequired) + { + return ConvertBigIntegerToFloatingPointBits( + ref integerValue, + in info, + integerBitsOfPrecision, + fractionalDigitsPresent != 0 + ); + } + + remainingBitsOfPrecisionRequired -= fractionalShift; + } + + // If there was no integer part of the mantissa, we will need to compute the + // exponent from the fractional part. The fractional exponent is the power + // of two by which we must multiply the fractional part to move it into the + // range [1.0, 2.0). This will either be the same as the shift we computed + // earlier, or one greater than that shift: + uint fractionalExponent = fractionalShift; + + if (BigInteger.Compare(ref fractionalNumerator, ref fractionalDenominator) < 0) + { + fractionalExponent++; + } + + fractionalNumerator.ShiftLeft(remainingBitsOfPrecisionRequired); + + BigInteger.DivRem(ref fractionalNumerator, ref fractionalDenominator, out BigInteger bigFractionalMantissa, out BigInteger fractionalRemainder); + ulong fractionalMantissa = bigFractionalMantissa.ToUInt64(); + bool hasZeroTail = !number.HasNonZeroTail && fractionalRemainder.IsZero(); + + // We may have produced more bits of precision than were required. Check, + // and remove any "extra" bits: + uint fractionalMantissaBits = BigInteger.CountSignificantBits(fractionalMantissa); + + if (fractionalMantissaBits > requiredFractionalBitsOfPrecision) + { + int shift = (int)(fractionalMantissaBits - requiredFractionalBitsOfPrecision); + hasZeroTail = hasZeroTail && (fractionalMantissa & ((1UL << shift) - 1)) == 0; + fractionalMantissa >>= shift; + } + + // Compose the mantissa from the integer and fractional parts: + ulong integerMantissa = integerValue.ToUInt64(); + ulong completeMantissa = (integerMantissa << (int)(requiredFractionalBitsOfPrecision)) + fractionalMantissa; + + // Compute the final exponent: + // * If the mantissa had an integer part, then the exponent is one less than + // the number of bits we obtained from the integer part. (It's one less + // because we are converting to the form 1.11111, with one 1 to the left + // of the decimal point.) + // * If the mantissa had no integer part, then the exponent is the fractional + // exponent that we computed. + // Then, in both cases, we subtract an additional one from the exponent, to + // account for the fact that we've generated an extra bit of precision, for + // use in rounding. + int finalExponent = (integerBitsOfPrecision > 0) ? (int)(integerBitsOfPrecision) - 2 : -(int)(fractionalExponent) - 1; + + return AssembleFloatingPointBits(in info, completeMantissa, finalExponent, hasZeroTail); + } + + private static ulong RightShiftWithRounding(ulong value, int shift, bool hasZeroTail) + { + // If we'd need to shift further than it is possible to shift, the answer + // is always zero: + if (shift >= 64) + { + return 0; + } + + ulong extraBitsMask = (1UL << (shift - 1)) - 1; + ulong roundBitMask = (1UL << (shift - 1)); + ulong lsbBitMask = 1UL << shift; + + bool lsbBit = (value & lsbBitMask) != 0; + bool roundBit = (value & roundBitMask) != 0; + bool hasTailBits = !hasZeroTail || (value & extraBitsMask) != 0; + + return (value >> shift) + (ShouldRoundUp(lsbBit, roundBit, hasTailBits) ? 1UL : 0); + } + + private static bool ShouldRoundUp(bool lsbBit, bool roundBit, bool hasTailBits) + { + // If there are insignificant set bits, we need to round to the + // nearest; there are two cases: + // we round up if either [1] the value is slightly greater than the midpoint + // between two exactly representable values or [2] the value is exactly the + // midpoint between two exactly representable values and the greater of the + // two is even (this is "round-to-even"). + return roundBit && (hasTailBits || lsbBit); + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Parsing.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Parsing.cs new file mode 100644 index 00000000..42924699 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Parsing.cs @@ -0,0 +1,2028 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System +{ + // The Parse methods provided by the numeric classes convert a + // string to a numeric value. The optional style parameter specifies the + // permitted style of the numeric string. It must be a combination of bit flags + // from the NumberStyles enumeration. The optional info parameter + // specifies the NumberFormatInfo instance to use when parsing the + // string. If the info parameter is null or omitted, the numeric + // formatting information is obtained from the current culture. + // + // Numeric strings produced by the Format methods using the Currency, + // Decimal, Engineering, Fixed point, General, or Number standard formats + // (the C, D, E, F, G, and N format specifiers) are guaranteed to be parseable + // by the Parse methods if the NumberStyles.Any style is + // specified. Note, however, that the Parse methods do not accept + // NaNs or Infinities. + + internal static partial class Number + { + private const int Int32Precision = 10; + private const int UInt32Precision = Int32Precision; + private const int Int64Precision = 19; + private const int UInt64Precision = 20; + + private const int DoubleMaxExponent = 309; + private const int DoubleMinExponent = -324; + + private const int FloatingPointMaxExponent = DoubleMaxExponent; + private const int FloatingPointMinExponent = DoubleMinExponent; + + private const int SingleMaxExponent = 39; + private const int SingleMinExponent = -45; + + /// Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit. + internal static ReadOnlySpan CharToHexLookup => new byte[] + { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 15 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 31 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 47 + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 63 + 0xFF, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 79 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 95 + 0xFF, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf // 102 + }; + + private static unsafe bool TryNumberToInt32(ref NumberBuffer number, ref int value) + { + number.CheckConsistency(); + + int i = number.Scale; + if (i > Int32Precision || i < number.DigitsCount) + { + return false; + } + byte* p = number.GetDigitsPointer(); + Debug.Assert(p != null); + int n = 0; + while (--i >= 0) + { + if ((uint)n > (0x7FFFFFFF / 10)) + { + return false; + } + n *= 10; + if (*p != '\0') + { + n += (*p++ - '0'); + } + } + if (number.IsNegative) + { + n = -n; + if (n > 0) + { + return false; + } + } + else + { + if (n < 0) + { + return false; + } + } + value = n; + return true; + } + + private static unsafe bool TryNumberToInt64(ref NumberBuffer number, ref long value) + { + number.CheckConsistency(); + + int i = number.Scale; + if (i > Int64Precision || i < number.DigitsCount) + { + return false; + } + byte* p = number.GetDigitsPointer(); + Debug.Assert(p != null); + long n = 0; + while (--i >= 0) + { + if ((ulong)n > (0x7FFFFFFFFFFFFFFF / 10)) + { + return false; + } + n *= 10; + if (*p != '\0') + { + n += (*p++ - '0'); + } + } + if (number.IsNegative) + { + n = -n; + if (n > 0) + { + return false; + } + } + else + { + if (n < 0) + { + return false; + } + } + value = n; + return true; + } + + private static unsafe bool TryNumberToUInt32(ref NumberBuffer number, ref uint value) + { + number.CheckConsistency(); + + int i = number.Scale; + if (i > UInt32Precision || i < number.DigitsCount || number.IsNegative) + { + return false; + } + byte* p = number.GetDigitsPointer(); + Debug.Assert(p != null); + uint n = 0; + while (--i >= 0) + { + if (n > (0xFFFFFFFF / 10)) + { + return false; + } + n *= 10; + if (*p != '\0') + { + uint newN = n + (uint)(*p++ - '0'); + // Detect an overflow here... + if (newN < n) + { + return false; + } + n = newN; + } + } + value = n; + return true; + } + + private static unsafe bool TryNumberToUInt64(ref NumberBuffer number, ref ulong value) + { + number.CheckConsistency(); + + int i = number.Scale; + if (i > UInt64Precision || i < number.DigitsCount || number.IsNegative) + { + return false; + } + byte* p = number.GetDigitsPointer(); + Debug.Assert(p != null); + ulong n = 0; + while (--i >= 0) + { + if (n > (0xFFFFFFFFFFFFFFFF / 10)) + { + return false; + } + n *= 10; + if (*p != '\0') + { + ulong newN = n + (ulong)(*p++ - '0'); + // Detect an overflow here... + if (newN < n) + { + return false; + } + n = newN; + } + } + value = n; + return true; + } + + internal static int ParseInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseInt32(value, styles, info, out int result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.Int32); + } + + return result; + } + + internal static long ParseInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseInt64(value, styles, info, out long result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.Int64); + } + + return result; + } + + internal static uint ParseUInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseUInt32(value, styles, info, out uint result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.UInt32); + } + + return result; + } + + internal static ulong ParseUInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseUInt64(value, styles, info, out ulong result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.UInt64); + } + + return result; + } + + private static unsafe bool TryParseNumber(ref char* str, char* strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info) + { + Debug.Assert(str != null); + Debug.Assert(strEnd != null); + Debug.Assert(str <= strEnd); + Debug.Assert((styles & NumberStyles.AllowHexSpecifier) == 0); + + const int StateSign = 0x0001; + const int StateParens = 0x0002; + const int StateDigits = 0x0004; + const int StateNonZero = 0x0008; + const int StateDecimal = 0x0010; + const int StateCurrency = 0x0020; + + Debug.Assert(number.DigitsCount == 0); + Debug.Assert(number.Scale == 0); + Debug.Assert(!number.IsNegative); + Debug.Assert(!number.HasNonZeroTail); + + number.CheckConsistency(); + + string decSep; // decimal separator from NumberFormatInfo. + string groupSep; // group separator from NumberFormatInfo. + string currSymbol = null; // currency symbol from NumberFormatInfo. + + bool parsingCurrency = false; + if ((styles & NumberStyles.AllowCurrencySymbol) != 0) + { + currSymbol = info.CurrencySymbol; + + // The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast. + // The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part). + decSep = info.CurrencyDecimalSeparator; + groupSep = info.CurrencyGroupSeparator; + parsingCurrency = true; + } + else + { + decSep = info.NumberDecimalSeparator; + groupSep = info.NumberGroupSeparator; + } + + int state = 0; + char* p = str; + char ch = p < strEnd ? *p : '\0'; + char* next; + + while (true) + { + // Eat whitespace unless we've found a sign which isn't followed by a currency symbol. + // "-Kr 1231.47" is legal but "- 1231.47" is not. + if (!IsWhite(ch) || (styles & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && info.NumberNegativePattern != 2))) + { + if ((((styles & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || ((next = MatchChars(p, strEnd, info.NegativeSign)) != null && (number.IsNegative = true)))) + { + state |= StateSign; + p = next - 1; + } + else if (ch == '(' && ((styles & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0)) + { + state |= StateSign | StateParens; + number.IsNegative = true; + } + else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) + { + state |= StateCurrency; + currSymbol = null; + // We already found the currency symbol. There should not be more currency symbols. Set + // currSymbol to NULL so that we won't search it again in the later code path. + p = next - 1; + } + else + { + break; + } + } + ch = ++p < strEnd ? *p : '\0'; + } + + int digCount = 0; + int digEnd = 0; + int maxDigCount = number.Digits.Length - 1; + + while (true) + { + if (IsDigit(ch)) + { + state |= StateDigits; + + if (ch != '0' || (state & StateNonZero) != 0) + { + if (digCount < maxDigCount) + { + number.Digits[digCount++] = (byte)(ch); + if ((ch != '0') || (number.Kind != NumberBufferKind.Integer)) + { + digEnd = digCount; + } + } + else if (ch != '0') + { + // For decimal and binary floating-point numbers, we only + // need to store digits up to maxDigCount. However, we still + // need to keep track of whether any additional digits past + // maxDigCount were non-zero, as that can impact rounding + // for an input that falls evenly between two representable + // results. + + number.HasNonZeroTail = true; + } + + if ((state & StateDecimal) == 0) + { + number.Scale++; + } + state |= StateNonZero; + } + else if ((state & StateDecimal) != 0) + { + number.Scale--; + } + } + else if (((styles & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, decSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberDecimalSeparator)) != null)) + { + state |= StateDecimal; + p = next - 1; + } + else if (((styles & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, groupSep)) != null || (parsingCurrency && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, info.NumberGroupSeparator)) != null)) + { + p = next - 1; + } + else + { + break; + } + ch = ++p < strEnd ? *p : '\0'; + } + + bool negExp = false; + number.DigitsCount = digEnd; + number.Digits[digEnd] = (byte)('\0'); + if ((state & StateDigits) != 0) + { + if ((ch == 'E' || ch == 'e') && ((styles & NumberStyles.AllowExponent) != 0)) + { + char* temp = p; + ch = ++p < strEnd ? *p : '\0'; + if ((next = MatchChars(p, strEnd, info.PositiveSign)) != null) + { + ch = (p = next) < strEnd ? *p : '\0'; + } + else if ((next = MatchChars(p, strEnd, info.NegativeSign)) != null) + { + ch = (p = next) < strEnd ? *p : '\0'; + negExp = true; + } + if (IsDigit(ch)) + { + int exp = 0; + do + { + exp = exp * 10 + (ch - '0'); + ch = ++p < strEnd ? *p : '\0'; + if (exp > 1000) + { + exp = 9999; + while (IsDigit(ch)) + { + ch = ++p < strEnd ? *p : '\0'; + } + } + } while (IsDigit(ch)); + if (negExp) + { + exp = -exp; + } + number.Scale += exp; + } + else + { + p = temp; + ch = p < strEnd ? *p : '\0'; + } + } + while (true) + { + if (!IsWhite(ch) || (styles & NumberStyles.AllowTrailingWhite) == 0) + { + if ((styles & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0) && ((next = MatchChars(p, strEnd, info.PositiveSign)) != null || (((next = MatchChars(p, strEnd, info.NegativeSign)) != null) && (number.IsNegative = true)))) + { + state |= StateSign; + p = next - 1; + } + else if (ch == ')' && ((state & StateParens) != 0)) + { + state &= ~StateParens; + } + else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null) + { + currSymbol = null; + p = next - 1; + } + else + { + break; + } + } + ch = ++p < strEnd ? *p : '\0'; + } + if ((state & StateParens) == 0) + { + if ((state & StateNonZero) == 0) + { + if (number.Kind != NumberBufferKind.Decimal) + { + number.Scale = 0; + } + if ((number.Kind == NumberBufferKind.Integer) && (state & StateDecimal) == 0) + { + number.IsNegative = false; + } + } + str = p; + return true; + } + } + str = p; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ParsingStatus TryParseInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) + { + if ((styles & ~NumberStyles.Integer) == 0) + { + // Optimized path for the common case of anything that's allowed for integer style. + return TryParseInt32IntegerStyle(value, styles, info, out result); + } + + if ((styles & NumberStyles.AllowHexSpecifier) != 0) + { + result = 0; + return TryParseUInt32HexNumberStyle(value, styles, out Unsafe.As(ref result)); + } + + return TryParseInt32Number(value, styles, info, out result); + } + + private static unsafe ParsingStatus TryParseInt32Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) + { + result = 0; + byte* pDigits = stackalloc byte[Int32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToInt32(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + /// Parses int limited to styles that make up NumberStyles.Integer. + internal static ParsingStatus TryParseInt32IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out int result) + { + Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + // Parse leading sign. + int sign = 1; + if ((styles & NumberStyles.AllowLeadingSign) != 0) + { + if (info.HasInvariantNumberSigns()) + { + if (num == '-') + { + sign = -1; + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (num == '+') + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + else + { + value = value.Slice(index); + index = 0; + string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; + if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) + { + index += positiveSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) + { + sign = -1; + index += negativeSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + } + + bool overflow = false; + int answer = 0; + + if (IsDigit(num)) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if (!IsDigit(num)) + goto HasTrailingChars; + } + + // Parse most digits, up to the potential for overflow, which can't happen until after 9 digits. + answer = num - '0'; // first digit + index++; + for (int i = 0; i < 8; i++) // next 8 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + answer = 10 * answer + num - '0'; + } + + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + // Potential overflow now processing the 10th digit. + overflow = answer > int.MaxValue / 10; + answer = answer * 10 + num - '0'; + overflow |= (uint)answer > int.MaxValue + (((uint)sign) >> 31); + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. + num = value[index]; + while (IsDigit(num)) + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = answer * sign; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + /// Parses long inputs limited to styles that make up NumberStyles.Integer. + internal static ParsingStatus TryParseInt64IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) + { + Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + // Parse leading sign. + int sign = 1; + if ((styles & NumberStyles.AllowLeadingSign) != 0) + { + if (info.HasInvariantNumberSigns()) + { + if (num == '-') + { + sign = -1; + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (num == '+') + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + else + { + value = value.Slice(index); + index = 0; + string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; + if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) + { + index += positiveSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) + { + sign = -1; + index += negativeSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + } + + bool overflow = false; + long answer = 0; + + if (IsDigit(num)) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if (!IsDigit(num)) + goto HasTrailingChars; + } + + // Parse most digits, up to the potential for overflow, which can't happen until after 18 digits. + answer = num - '0'; // first digit + index++; + for (int i = 0; i < 17; i++) // next 17 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + answer = 10 * answer + num - '0'; + } + + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + // Potential overflow now processing the 19th digit. + overflow = answer > long.MaxValue / 10; + answer = answer * 10 + num - '0'; + overflow |= (ulong)answer > (ulong)long.MaxValue + (((uint)sign) >> 31); + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. + num = value[index]; + while (IsDigit(num)) + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = answer * sign; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ParsingStatus TryParseInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) + { + if ((styles & ~NumberStyles.Integer) == 0) + { + // Optimized path for the common case of anything that's allowed for integer style. + return TryParseInt64IntegerStyle(value, styles, info, out result); + } + + if ((styles & NumberStyles.AllowHexSpecifier) != 0) + { + result = 0; + return TryParseUInt64HexNumberStyle(value, styles, out Unsafe.As(ref result)); + } + + return TryParseInt64Number(value, styles, info, out result); + } + + private static unsafe ParsingStatus TryParseInt64Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out long result) + { + result = 0; + byte* pDigits = stackalloc byte[Int64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToInt64(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ParsingStatus TryParseUInt32(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) + { + if ((styles & ~NumberStyles.Integer) == 0) + { + // Optimized path for the common case of anything that's allowed for integer style. + return TryParseUInt32IntegerStyle(value, styles, info, out result); + } + + if ((styles & NumberStyles.AllowHexSpecifier) != 0) + { + return TryParseUInt32HexNumberStyle(value, styles, out result); + } + + return TryParseUInt32Number(value, styles, info, out result); + } + + private static unsafe ParsingStatus TryParseUInt32Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) + { + result = 0; + byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToUInt32(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + /// Parses uint limited to styles that make up NumberStyles.Integer. + internal static ParsingStatus TryParseUInt32IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out uint result) + { + Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + // Parse leading sign. + bool overflow = false; + if ((styles & NumberStyles.AllowLeadingSign) != 0) + { + if (info.HasInvariantNumberSigns()) + { + if (num == '+') + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (num == '-') + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + else + { + value = value.Slice(index); + index = 0; + string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; + if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) + { + index += positiveSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) + { + overflow = true; + index += negativeSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + } + + int answer = 0; + + if (IsDigit(num)) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if (!IsDigit(num)) + goto HasTrailingCharsZero; + } + + // Parse most digits, up to the potential for overflow, which can't happen until after 9 digits. + answer = num - '0'; // first digit + index++; + for (int i = 0; i < 8; i++) // next 8 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + answer = 10 * answer + num - '0'; + } + + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + // Potential overflow now processing the 10th digit. + overflow |= (uint)answer > uint.MaxValue / 10 || ((uint)answer == uint.MaxValue / 10 && num > '5'); + answer = answer * 10 + num - '0'; + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. + num = value[index]; + while (IsDigit(num)) + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = (uint)answer; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingCharsZero: + overflow = false; + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + /// Parses uint limited to styles that make up NumberStyles.HexNumber. + private static ParsingStatus TryParseUInt32HexNumberStyle(ReadOnlySpan value, NumberStyles styles, out uint result) + { + Debug.Assert((styles & ~NumberStyles.HexNumber) == 0, "Only handles subsets of HexNumber format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + bool overflow = false; + uint answer = 0; + ReadOnlySpan charToHexLookup = CharToHexLookup; + + if ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) + goto HasTrailingChars; + } + + // Parse up through 8 digits, as no overflow is possible + answer = charToHexLookup[num]; // first digit + index++; + for (int i = 0; i < 7; i++) // next 7 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + + uint numValue; + if ((uint)num >= (uint)charToHexLookup.Length || (numValue = charToHexLookup[num]) == 0xFF) + goto HasTrailingChars; + index++; + answer = 16 * answer + numValue; + } + + // If there's another digit, it's an overflow. + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) + goto HasTrailingChars; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. Read through any remaining digits. + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } while ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF); + overflow = true; + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = answer; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ParsingStatus TryParseUInt64(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) + { + if ((styles & ~NumberStyles.Integer) == 0) + { + // Optimized path for the common case of anything that's allowed for integer style. + return TryParseUInt64IntegerStyle(value, styles, info, out result); + } + + if ((styles & NumberStyles.AllowHexSpecifier) != 0) + { + return TryParseUInt64HexNumberStyle(value, styles, out result); + } + + return TryParseUInt64Number(value, styles, info, out result); + } + + private static unsafe ParsingStatus TryParseUInt64Number(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) + { + result = 0; + byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToUInt64(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + /// Parses ulong limited to styles that make up NumberStyles.Integer. + internal static ParsingStatus TryParseUInt64IntegerStyle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out ulong result) + { + Debug.Assert((styles & ~NumberStyles.Integer) == 0, "Only handles subsets of Integer format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + // Parse leading sign. + bool overflow = false; + if ((styles & NumberStyles.AllowLeadingSign) != 0) + { + if (info.HasInvariantNumberSigns()) + { + if (num == '+') + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (num == '-') + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + else + { + value = value.Slice(index); + index = 0; + string positiveSign = info.PositiveSign, negativeSign = info.NegativeSign; + if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign.AsSpan())) + { + index += positiveSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign.AsSpan())) + { + overflow = true; + index += negativeSign.Length; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + } + } + + long answer = 0; + + if (IsDigit(num)) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if (!IsDigit(num)) + goto HasTrailingCharsZero; + } + + // Parse most digits, up to the potential for overflow, which can't happen until after 19 digits. + answer = num - '0'; // first digit + index++; + for (int i = 0; i < 18; i++) // next 18 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + answer = 10 * answer + num - '0'; + } + + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + num = value[index]; + if (!IsDigit(num)) + goto HasTrailingChars; + index++; + // Potential overflow now processing the 20th digit. + overflow |= (ulong)answer > ulong.MaxValue / 10 || ((ulong)answer == ulong.MaxValue / 10 && num > '5'); + answer = answer * 10 + num - '0'; + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. + num = value[index]; + while (IsDigit(num)) + { + overflow = true; + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = (ulong)answer; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingCharsZero: + overflow = false; + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + /// Parses ulong limited to styles that make up NumberStyles.HexNumber. + private static ParsingStatus TryParseUInt64HexNumberStyle(ReadOnlySpan value, NumberStyles styles, out ulong result) + { + Debug.Assert((styles & ~NumberStyles.HexNumber) == 0, "Only handles subsets of HexNumber format"); + + if (value.IsEmpty) + goto FalseExit; + + int index = 0; + int num = value[0]; + + // Skip past any whitespace at the beginning. + if ((styles & NumberStyles.AllowLeadingWhite) != 0 && IsWhite(num)) + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto FalseExit; + num = value[index]; + } + while (IsWhite(num)); + } + + bool overflow = false; + ulong answer = 0; + ReadOnlySpan charToHexLookup = CharToHexLookup; + + if ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF) + { + // Skip past leading zeros. + if (num == '0') + { + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + } while (num == '0'); + if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) + goto HasTrailingChars; + } + + // Parse up through 16 digits, as no overflow is possible + answer = charToHexLookup[num]; // first digit + index++; + for (int i = 0; i < 15; i++) // next 15 digits can't overflow + { + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + + uint numValue; + if ((uint)num >= (uint)charToHexLookup.Length || (numValue = charToHexLookup[num]) == 0xFF) + goto HasTrailingChars; + index++; + answer = 16 * answer + numValue; + } + + // If there's another digit, it's an overflow. + if ((uint)index >= (uint)value.Length) + goto DoneAtEnd; + num = value[index]; + if ((uint)num >= (uint)charToHexLookup.Length || charToHexLookup[num] == 0xFF) + goto HasTrailingChars; + + // At this point, we're either overflowing or hitting a formatting error. + // Format errors take precedence for compatibility. Read through any remaining digits. + do + { + index++; + if ((uint)index >= (uint)value.Length) + goto OverflowExit; + num = value[index]; + } while ((uint)num < (uint)charToHexLookup.Length && charToHexLookup[num] != 0xFF); + overflow = true; + goto HasTrailingChars; + } + goto FalseExit; + + DoneAtEndButPotentialOverflow: + if (overflow) + { + goto OverflowExit; + } + DoneAtEnd: + result = answer; + ParsingStatus status = ParsingStatus.OK; + Exit: + return status; + + FalseExit: // parsing failed + result = 0; + status = ParsingStatus.Failed; + goto Exit; + OverflowExit: + result = 0; + status = ParsingStatus.Overflow; + goto Exit; + + HasTrailingChars: // we've successfully parsed, but there are still remaining characters in the span + // Skip past trailing whitespace, then past trailing zeros, and if anything else remains, fail. + if (IsWhite(num)) + { + if ((styles & NumberStyles.AllowTrailingWhite) == 0) + goto FalseExit; + for (index++; index < value.Length; index++) + { + if (!IsWhite(value[index])) + break; + } + if ((uint)index >= (uint)value.Length) + goto DoneAtEndButPotentialOverflow; + } + + if (!TrailingZeros(value, index)) + goto FalseExit; + + goto DoneAtEndButPotentialOverflow; + } + + internal static decimal ParseDecimal(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + ParsingStatus status = TryParseDecimal(value, styles, info, out decimal result); + if (status != ParsingStatus.OK) + { + ThrowOverflowOrFormatException(status, TypeCode.Decimal); + } + + return result; + } + + internal static unsafe bool TryNumberToDecimal(ref NumberBuffer number, ref decimal value) + { + number.CheckConsistency(); + + byte* p = number.GetDigitsPointer(); + int e = number.Scale; + bool sign = number.IsNegative; + uint c = *p; + if (c == 0) + { + // To avoid risking an app-compat issue with pre 4.5 (where some app was illegally using Reflection to examine the internal scale bits), we'll only force + // the scale to 0 if the scale was previously positive (previously, such cases were unparsable to a bug.) + value = new decimal(0, 0, 0, sign, (byte)MathEx.Clamp(-e, 0, 28)); + return true; + } + + if (e > DecimalPrecision) + return false; + + ulong low64 = 0; + while (e > -28) + { + e--; + low64 *= 10; + low64 += c - '0'; + c = *++p; + if (low64 >= ulong.MaxValue / 10) + break; + if (c == 0) + { + while (e > 0) + { + e--; + low64 *= 10; + if (low64 >= ulong.MaxValue / 10) + break; + } + break; + } + } + + uint high = 0; + while ((e > 0 || (c != 0 && e > -28)) && + (high < uint.MaxValue / 10 || (high == uint.MaxValue / 10 && (low64 < 0x99999999_99999999 || (low64 == 0x99999999_99999999 && c <= '5'))))) + { + // multiply by 10 + ulong tmpLow = (uint)low64 * 10UL; + ulong tmp64 = (uint)(low64 >> 32) * 10UL + (tmpLow >> 32); + low64 = (uint)tmpLow + (tmp64 << 32); + high = (uint)(tmp64 >> 32) + high * 10; + + if (c != 0) + { + c -= '0'; + low64 += c; + if (low64 < c) + high++; + c = *++p; + } + e--; + } + + if (c >= '5') + { + if ((c == '5') && ((low64 & 1) == 0)) + { + c = *++p; + + bool hasZeroTail = !number.HasNonZeroTail; + + // We might still have some additional digits, in which case they need + // to be considered as part of hasZeroTail. Some examples of this are: + // * 3.0500000000000000000001e-27 + // * 3.05000000000000000000001e-27 + // In these cases, we will have processed 3 and 0, and ended on 5. The + // buffer, however, will still contain a number of trailing zeros and + // a trailing non-zero number. + + while ((c != 0) && hasZeroTail) + { + hasZeroTail &= (c == '0'); + c = *++p; + } + + // We should either be at the end of the stream or have a non-zero tail + Debug.Assert((c == 0) || !hasZeroTail); + + if (hasZeroTail) + { + // When the next digit is 5, the number is even, and all following + // digits are zero we don't need to round. + goto NoRounding; + } + } + + if (++low64 == 0 && ++high == 0) + { + low64 = 0x99999999_9999999A; + high = uint.MaxValue / 10; + e++; + } + } + NoRounding: + + if (e > 0) + return false; + + if (e <= -DecimalPrecision) + { + // Parsing a large scale zero can give you more precision than fits in the decimal. + // This should only happen for actual zeros or very small numbers that round to zero. + value = new decimal(0, 0, 0, sign, DecimalPrecision - 1); + } + else + { + value = new decimal((int)low64, (int)(low64 >> 32), (int)high, sign, (byte)-e); + } + return true; + } + + internal static double ParseDouble(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + if (!TryParseDouble(value, styles, info, out double result)) + { + ThrowOverflowOrFormatException(ParsingStatus.Failed); + } + + return result; + } + + internal static float ParseSingle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info) + { + if (!TryParseSingle(value, styles, info, out float result)) + { + ThrowOverflowOrFormatException(ParsingStatus.Failed); + } + + return result; + } + + internal static unsafe ParsingStatus TryParseDecimal(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out decimal result) + { + byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); + + result = 0; + + if (!TryStringToNumber(value, styles, ref number, info)) + { + return ParsingStatus.Failed; + } + + if (!TryNumberToDecimal(ref number, ref result)) + { + return ParsingStatus.Overflow; + } + + return ParsingStatus.OK; + } + + internal static unsafe bool TryParseDouble(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out double result) + { + byte* pDigits = stackalloc byte[DoubleNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, DoubleNumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + ReadOnlySpan valueTrim = value.Trim(); + + // This code would be simpler if we only had the concept of `InfinitySymbol`, but + // we don't so we'll check the existing cases first and then handle `PositiveSign` + + // `PositiveInfinitySymbol` and `PositiveSign/NegativeSign` + `NaNSymbol` last. + + if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) + { + result = double.PositiveInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol.AsSpan())) + { + result = double.NegativeInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = double.NaN; + } + else if (valueTrim.StartsWith(info.PositiveSign.AsSpan(), StringComparison.OrdinalIgnoreCase)) + { + valueTrim = valueTrim.Slice(info.PositiveSign.Length); + + if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) + { + result = double.PositiveInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = double.NaN; + } + else + { + result = 0; + return false; + } + } + else if (valueTrim.StartsWith(info.NegativeSign.AsSpan(), StringComparison.OrdinalIgnoreCase) && + valueTrim.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = double.NaN; + } + else + { + result = 0; + return false; // We really failed + } + } + else + { + result = NumberToDouble(ref number); + } + + return true; + } + + internal static unsafe bool TryParseSingle(ReadOnlySpan value, NumberStyles styles, NumberFormatInfo info, out float result) + { + byte* pDigits = stackalloc byte[SingleNumberBufferLength]; + NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, SingleNumberBufferLength); + + if (!TryStringToNumber(value, styles, ref number, info)) + { + ReadOnlySpan valueTrim = value.Trim(); + + // This code would be simpler if we only had the concept of `InfinitySymbol`, but + // we don't so we'll check the existing cases first and then handle `PositiveSign` + + // `PositiveInfinitySymbol` and `PositiveSign/NegativeSign` + `NaNSymbol` last. + // + // Additionally, since some cultures ("wo") actually define `PositiveInfinitySymbol` + // to include `PositiveSign`, we need to check whether `PositiveInfinitySymbol` fits + // that case so that we don't start parsing things like `++infini`. + + if (valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) + { + result = float.PositiveInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol.AsSpan())) + { + result = float.NegativeInfinity; + } + else if (valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = float.NaN; + } + else if (valueTrim.StartsWith(info.PositiveSign.AsSpan(), StringComparison.OrdinalIgnoreCase)) + { + valueTrim = valueTrim.Slice(info.PositiveSign.Length); + + if (!info.PositiveInfinitySymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) && valueTrim.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol.AsSpan())) + { + result = float.PositiveInfinity; + } + else if (!info.NaNSymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) && valueTrim.EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = float.NaN; + } + else + { + result = 0; + return false; + } + } + else if (valueTrim.StartsWith(info.NegativeSign.AsSpan(), StringComparison.OrdinalIgnoreCase) && + !info.NaNSymbol.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) && + valueTrim.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol.AsSpan())) + { + result = float.NaN; + } + else + { + result = 0; + return false; // We really failed + } + } + else + { + result = NumberToSingle(ref number); + } + + return true; + } + + internal static unsafe bool TryStringToNumber(ReadOnlySpan value, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info) + { + Debug.Assert(info != null); + fixed (char* stringPointer = &MemoryMarshal.GetReference(value)) + { + char* p = stringPointer; + if (!TryParseNumber(ref p, p + value.Length, styles, ref number, info) + || ((int)(p - stringPointer) < value.Length && !TrailingZeros(value, (int)(p - stringPointer)))) + { + number.CheckConsistency(); + return false; + } + } + + number.CheckConsistency(); + return true; + } + + private static bool TrailingZeros(ReadOnlySpan value, int index) + { + // For compatibility, we need to allow trailing zeros at the end of a number string + for (int i = index; (uint)i < (uint)value.Length; i++) + { + if (value[i] != '\0') + { + return false; + } + } + + return true; + } + + private static bool IsSpaceReplacingChar(char c) => c == '\u00a0' || c == '\u202f'; + + private static unsafe char* MatchChars(char* p, char* pEnd, string value) + { + Debug.Assert(p != null && pEnd != null && p <= pEnd && value != null); + fixed (char* stringPointer = value) + { + char* str = stringPointer; + if (*str != '\0') + { + // We only hurt the failure case + // This fix is for French or Kazakh cultures. Since a user cannot type 0xA0 or 0x202F as a + // space character we use 0x20 space character instead to mean the same. + while (true) + { + char cp = p < pEnd ? *p : '\0'; + if (cp != *str && !(IsSpaceReplacingChar(*str) && cp == '\u0020')) + { + break; + } + p++; + str++; + if (*str == '\0') + return p; + } + } + } + + return null; + } + + // Ternary op is a workaround for https://github.com/dotnet/coreclr/issues/914 + private static bool IsWhite(int ch) => ch == 0x20 || (uint)(ch - 0x09) <= (0x0D - 0x09) ? true : false; + + private static bool IsDigit(int ch) => ((uint)ch - '0') <= 9; + + internal enum ParsingStatus + { + OK, + Failed, + Overflow + } + + internal static void ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type = 0) => throw GetException(status, type); + + internal static void ThrowOverflowException(TypeCode type) => throw GetException(ParsingStatus.Overflow, type); + + private static Exception GetException(ParsingStatus status, TypeCode type) + { + if (status == ParsingStatus.Failed) + return new FormatException(); + + string s; + switch (type) + { + case TypeCode.SByte: + s = "SR.Overflow_SByte"; + break; + case TypeCode.Byte: + s = "SR.Overflow_Byte"; + break; + case TypeCode.Int16: + s = "SR.Overflow_Int16"; + break; + case TypeCode.UInt16: + s = "SR.Overflow_UInt16"; + break; + case TypeCode.Int32: + s = "SR.Overflow_Int32"; + break; + case TypeCode.UInt32: + s = "SR.Overflow_UInt32"; + break; + case TypeCode.Int64: + s = "SR.Overflow_Int64"; + break; + case TypeCode.UInt64: + s = "SR.Overflow_UInt64"; + break; + default: + Debug.Assert(type == TypeCode.Decimal); + s = "SR.Overflow_Decimal"; + break; + } + return new OverflowException(s); + } + + internal static double NumberToDouble(ref NumberBuffer number) + { + number.CheckConsistency(); + double result; + + if ((number.DigitsCount == 0) || (number.Scale < DoubleMinExponent)) + { + result = 0; + } + else if (number.Scale > DoubleMaxExponent) + { + result = double.PositiveInfinity; + } + else + { + ulong bits = NumberToFloatingPointBits(ref number, in FloatingPointInfo.Double); + result = BitConverter.Int64BitsToDouble((long)(bits)); + } + + return number.IsNegative ? -result : result; + } + + internal static float NumberToSingle(ref NumberBuffer number) + { + number.CheckConsistency(); + float result; + + if ((number.DigitsCount == 0) || (number.Scale < SingleMinExponent)) + { + result = 0; + } + else if (number.Scale > SingleMaxExponent) + { + result = float.PositiveInfinity; + } + else + { + uint bits = (uint)(NumberToFloatingPointBits(ref number, in FloatingPointInfo.Single)); + result = Int32BitsToSingle((int)(bits)); + } + + return number.IsNegative ? -result : result; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static unsafe float Int32BitsToSingle(int value) + { + return *((float*)&value); + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/NumberFormatInfoEx.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/NumberFormatInfoEx.cs new file mode 100644 index 00000000..785c6764 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/NumberFormatInfoEx.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace System +{ + internal static class NumberFormatInfoEx + { + internal static bool HasInvariantNumberSigns(this NumberFormatInfo info) + { + return info.PositiveSign == "+" && info.NegativeSign == "-"; + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/ValueStringBuilder.cs new file mode 100644 index 00000000..38afec71 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/ValueStringBuilder.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Text +{ + internal ref partial struct ValueStringBuilder + { + private char[] _arrayToReturnToPool; + private Span _chars; + private int _pos; + + public ValueStringBuilder(Span initialBuffer) + { + _arrayToReturnToPool = null; + _chars = initialBuffer; + _pos = 0; + } + + public ValueStringBuilder(int initialCapacity) + { + _arrayToReturnToPool = ArrayPool.Shared.Rent(initialCapacity); + _chars = _arrayToReturnToPool; + _pos = 0; + } + + public int Length + { + get => _pos; + set + { + Debug.Assert(value >= 0); + Debug.Assert(value <= _chars.Length); + _pos = value; + } + } + + public int Capacity => _chars.Length; + + public void EnsureCapacity(int capacity) + { + if (capacity > _chars.Length) + Grow(capacity - _pos); + } + + /// + /// Get a pinnable reference to the builder. + /// Does not ensure there is a null char after + /// This overload is pattern matched in the C# 7.3+ compiler so you can omit + /// the explicit method call, and write eg "fixed (char* c = builder)" + /// + public ref char GetPinnableReference() + { + return ref MemoryMarshal.GetReference(_chars); + } + + /// + /// Get a pinnable reference to the builder. + /// + /// Ensures that the builder has a null char after + public ref char GetPinnableReference(bool terminate) + { + if (terminate) + { + EnsureCapacity(Length + 1); + _chars[Length] = '\0'; + } + return ref MemoryMarshal.GetReference(_chars); + } + + public ref char this[int index] + { + get + { + Debug.Assert(index < _pos); + return ref _chars[index]; + } + } + + public override string ToString() + { + string s = _chars.Slice(0, _pos).ToString(); + Dispose(); + return s; + } + + /// Returns the underlying storage of the builder. + public Span RawChars => _chars; + + /// + /// Returns a span around the contents of the builder. + /// + /// Ensures that the builder has a null char after + public ReadOnlySpan AsSpan(bool terminate) + { + if (terminate) + { + EnsureCapacity(Length + 1); + _chars[Length] = '\0'; + } + return _chars.Slice(0, _pos); + } + + public ReadOnlySpan AsSpan() => _chars.Slice(0, _pos); + public ReadOnlySpan AsSpan(int start) => _chars.Slice(start, _pos - start); + public ReadOnlySpan AsSpan(int start, int length) => _chars.Slice(start, length); + + public bool TryCopyTo(Span destination, out int charsWritten) + { + if (_chars.Slice(0, _pos).TryCopyTo(destination)) + { + charsWritten = _pos; + Dispose(); + return true; + } + else + { + charsWritten = 0; + Dispose(); + return false; + } + } + + public void Insert(int index, char value, int count) + { + if (_pos > _chars.Length - count) + { + Grow(count); + } + + int remaining = _pos - index; + _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); + _chars.Slice(index, count).Fill(value); + _pos += count; + } + + public void Insert(int index, string s) + { + if (s == null) + { + return; + } + + int count = s.Length; + + if (_pos > (_chars.Length - count)) + { + Grow(count); + } + + int remaining = _pos - index; + _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); + s.AsSpan().CopyTo(_chars.Slice(index)); + _pos += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char c) + { + int pos = _pos; + if ((uint)pos < (uint)_chars.Length) + { + _chars[pos] = c; + _pos = pos + 1; + } + else + { + GrowAndAppend(c); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string s) + { + if (s == null) + { + return; + } + + int pos = _pos; + if (s.Length == 1 && (uint)pos < (uint)_chars.Length) // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. + { + _chars[pos] = s[0]; + _pos = pos + 1; + } + else + { + AppendSlow(s); + } + } + + private void AppendSlow(string s) + { + int pos = _pos; + if (pos > _chars.Length - s.Length) + { + Grow(s.Length); + } + + s.AsSpan().CopyTo(_chars.Slice(pos)); + _pos += s.Length; + } + + public void Append(char c, int count) + { + if (_pos > _chars.Length - count) + { + Grow(count); + } + + Span dst = _chars.Slice(_pos, count); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = c; + } + _pos += count; + } + + public unsafe void Append(char* value, int length) + { + int pos = _pos; + if (pos > _chars.Length - length) + { + Grow(length); + } + + Span dst = _chars.Slice(_pos, length); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = *value++; + } + _pos += length; + } + + public void Append(ReadOnlySpan value) + { + int pos = _pos; + if (pos > _chars.Length - value.Length) + { + Grow(value.Length); + } + + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span AppendSpan(int length) + { + int origPos = _pos; + if (origPos > _chars.Length - length) + { + Grow(length); + } + + _pos = origPos + length; + return _chars.Slice(origPos, length); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowAndAppend(char c) + { + Grow(1); + Append(c); + } + + /// + /// Resize the internal buffer either by doubling current buffer size or + /// by adding to + /// whichever is greater. + /// + /// + /// Number of chars requested beyond current position. + /// + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow(int additionalCapacityBeyondPos) + { + Debug.Assert(additionalCapacityBeyondPos > 0); + Debug.Assert(_pos > _chars.Length - additionalCapacityBeyondPos, "Grow called incorrectly, no resize is needed."); + + char[] poolArray = ArrayPool.Shared.Rent(Math.Max(_pos + additionalCapacityBeyondPos, _chars.Length * 2)); + + _chars.Slice(0, _pos).CopyTo(poolArray); + + char[] toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = poolArray; + if (toReturn != null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + char[] toReturn = _arrayToReturnToPool; + this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again + if (toReturn != null) + { + ArrayPool.Shared.Return(toReturn); + } + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/DecimalEx.cs b/src/ZString/Number/DecimalEx.cs index 098423fb..95125476 100644 --- a/src/ZString/Number/DecimalEx.cs +++ b/src/ZString/Number/DecimalEx.cs @@ -21,24 +21,73 @@ private struct DecimalBits public int mid; } + [StructLayout(LayoutKind.Explicit)] + private struct DecCalc + { + private const uint TenToPowerNine = 1000000000; + + // NOTE: Do not change the offsets of these fields. This structure must have the same layout as Decimal. + [FieldOffset(0)] + public uint uflags; + [FieldOffset(4)] + public uint uhi; + [FieldOffset(8)] + public uint ulo; + [FieldOffset(12)] + public uint umid; + + /// + /// The low and mid fields combined in little-endian order + /// + [FieldOffset(8)] + private ulong ulomidLE; + + internal static uint DecDivMod1E9(ref DecCalc value) + { + ulong high64 = ((ulong)value.uhi << 32) + value.umid; + ulong div64 = high64 / TenToPowerNine; + value.uhi = (uint)(div64 >> 32); + value.umid = (uint)div64; + + ulong num = ((high64 - (uint)div64 * TenToPowerNine) << 32) + value.ulo; + uint div = (uint)(num / TenToPowerNine); + value.ulo = div; + return (uint)num - div * TenToPowerNine; + } + } + + private const int ScaleShift = 16; + + static ref DecCalc AsMutable(ref decimal d) => ref Unsafe.As(ref d); + internal static uint High(this decimal value) { - return (uint)Unsafe.As(ref value).hi; + return Unsafe.As(ref value).uhi; } internal static uint Low(this decimal value) { - return (uint)Unsafe.As(ref value).lo; + return Unsafe.As(ref value).ulo; } internal static uint Mid(this decimal value) { - return (uint)Unsafe.As(ref value).mid; + return Unsafe.As(ref value).umid; } internal static bool IsNegative(this decimal value) { return Unsafe.As(ref value).flags < 0; } + + internal static int Scale(this decimal value) + { + return (byte)(Unsafe.As(ref value).flags >> ScaleShift); + } + + internal static uint DecDivMod1E9(ref decimal value) + { + return DecCalc.DecDivMod1E9(ref AsMutable(ref value)); + } } } diff --git a/src/ZString/Number/FormattingHelpers.cs b/src/ZString/Number/FormattingHelpers.cs new file mode 100644 index 00000000..7072b315 --- /dev/null +++ b/src/ZString/Number/FormattingHelpers.cs @@ -0,0 +1,138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System.Buffers.Text +{ + internal static partial class FormattingHelpers + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDigits(ulong value) + { + int digits = 1; + uint part; + if (value >= 10000000) + { + if (value >= 100000000000000) + { + part = (uint)(value / 100000000000000); + digits += 14; + } + else + { + part = (uint)(value / 10000000); + digits += 7; + } + } + else + { + part = (uint)value; + } + + if (part < 10) + { + // no-op + } + else if (part < 100) + { + digits++; + } + else if (part < 1000) + { + digits += 2; + } + else if (part < 10000) + { + digits += 3; + } + else if (part < 100000) + { + digits += 4; + } + else if (part < 1000000) + { + digits += 5; + } + else + { + Debug.Assert(part < 10000000); + digits += 6; + } + + return digits; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDigits(uint value) + { + int digits = 1; + if (value >= 100000) + { + value /= 100000; + digits += 5; + } + + if (value < 10) + { + // no-op + } + else if (value < 100) + { + digits++; + } + else if (value < 1000) + { + digits += 2; + } + else if (value < 10000) + { + digits += 3; + } + else + { + Debug.Assert(value < 100000); + digits += 4; + } + + return digits; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountHexDigits(ulong value) + { + return (64 - BitOperations.LeadingZeroCount(value | 1) + 3) >> 2; + } + + // Counts the number of trailing '0' digits in a decimal number. + // e.g., value = 0 => retVal = 0, valueWithoutTrailingZeros = 0 + // value = 1234 => retVal = 0, valueWithoutTrailingZeros = 1234 + // value = 320900 => retVal = 2, valueWithoutTrailingZeros = 3209 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDecimalTrailingZeros(uint value, out uint valueWithoutTrailingZeros) + { + int zeroCount = 0; + + if (value != 0) + { + while (true) + { + uint temp = value / 10; + if (value != (temp * 10)) + { + break; + } + + value = temp; + zeroCount++; + } + } + + valueWithoutTrailingZeros = value; + return zeroCount; + } + } +} \ No newline at end of file diff --git a/src/ZString/Number/MathEx.cs b/src/ZString/Number/MathEx.cs index c5f93b1d..b3a047c9 100644 --- a/src/ZString/Number/MathEx.cs +++ b/src/ZString/Number/MathEx.cs @@ -7,20 +7,34 @@ namespace System { internal static class MathEx { - internal static uint DivRem(uint a, uint b, out uint result) + public static uint DivRem(uint a, uint b, out uint result) { uint div = a / b; result = a - (div * b); return div; } - internal static ulong DivRem(ulong a, ulong b, out ulong result) + public static ulong DivRem(ulong a, ulong b, out ulong result) { ulong div = a / b; result = a - (div * b); return div; } + public static int DivRem(int a, int b, out int result) + { + int div = a / b; + result = a - (div * b); + return div; + } + + public static long DivRem(long a, long b, out long result) + { + long div = a / b; + result = a - (div * b); + return div; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte Clamp(byte value, byte min, byte max) { diff --git a/src/ZString/Number/Number.Formatting.cs b/src/ZString/Number/Number.Formatting.cs index a7bda20a..eb2d402f 100644 --- a/src/ZString/Number/Number.Formatting.cs +++ b/src/ZString/Number/Number.Formatting.cs @@ -356,14 +356,14 @@ internal static unsafe void DecimalToNumber(ref decimal d, ref NumberBuffer numb byte* p = buffer + DecimalPrecision; while ((d.Mid() | d.High()) != 0) { - p = UInt32ToDecChars(p, decimal.DecDivMod1E9(ref d), 9); + p = UInt32ToDecChars(p, DecimalEx.DecDivMod1E9(ref d), 9); } p = UInt32ToDecChars(p, d.Low(), 0); int i = (int)((buffer + DecimalPrecision) - p); number.DigitsCount = i; - number.Scale = i - d.Scale; + number.Scale = i - d.Scale(); byte* dst = number.GetDigitsPointer(); while (--i >= 0) @@ -505,7 +505,7 @@ private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int preci default: { - throw new FormatException(SR.Argument_BadFormatSpecifier); + throw new FormatException("SR.Argument_BadFormatSpecifier"); } } @@ -519,14 +519,14 @@ private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int preci /// private static unsafe string FormatDouble(ref ValueStringBuilder sb, double value, ReadOnlySpan format, NumberFormatInfo info) { - if (!double.IsFinite(value)) + if (!FloatEx.IsFinite(value)) { if (double.IsNaN(value)) { return info.NaNSymbol; } - return double.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; + return FloatEx.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; } char fmt = ParseFormatSpecifier(format, out int precision); @@ -540,7 +540,7 @@ private static unsafe string FormatDouble(ref ValueStringBuilder sb, double valu } NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, DoubleNumberBufferLength); - number.IsNegative = double.IsNegative(value); + number.IsNegative = FloatEx.IsNegative(value); // We need to track the original precision requested since some formats // accept values like 0 and others may require additional fixups. @@ -607,14 +607,14 @@ public static bool TryFormatSingle(float value, ReadOnlySpan format, Numbe /// private static unsafe string FormatSingle(ref ValueStringBuilder sb, float value, ReadOnlySpan format, NumberFormatInfo info) { - if (!float.IsFinite(value)) + if (!FloatEx.IsFinite(value)) { if (float.IsNaN(value)) { return info.NaNSymbol; } - return float.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; + return FloatEx.IsNegative(value) ? info.NegativeInfinitySymbol : info.PositiveInfinitySymbol; } char fmt = ParseFormatSpecifier(format, out int precision); @@ -628,7 +628,7 @@ private static unsafe string FormatSingle(ref ValueStringBuilder sb, float value } NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, SingleNumberBufferLength); - number.IsNegative = float.IsNegative(value); + number.IsNegative = FloatEx.IsNegative(value); // We need to track the original precision requested since some formats // accept values like 0 and others may require additional fixups. @@ -645,7 +645,7 @@ private static unsafe string FormatSingle(ref ValueStringBuilder sb, float value // because we know we have enough digits to satisfy roundtrippability), we should validate // that the number actually roundtrips back to the original result. - Debug.Assert(((precision != -1) && (precision < SinglePrecision)) || (BitConverter.SingleToInt32Bits(value) == BitConverter.SingleToInt32Bits(NumberToSingle(ref number)))); + Debug.Assert(((precision != -1) && (precision < SinglePrecision)) || (SingleToInt32Bits(value) == SingleToInt32Bits(NumberToSingle(ref number)))); if (fmt != 0) { @@ -1088,7 +1088,7 @@ private static unsafe string NegativeInt32ToDecStr(int value, int digits, string digits = 1; int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; - string result = string.FastAllocateString(bufferLength); + string result = FastAllocateString(bufferLength); fixed (char* buffer = result) { char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); @@ -1138,7 +1138,7 @@ private static unsafe string Int32ToHexStr(int value, char hexBase, int digits) digits = 1; int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); - string result = string.FastAllocateString(bufferLength); + string result = FastAllocateString(bufferLength); fixed (char* buffer = result) { char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); @@ -1205,7 +1205,7 @@ private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) { while (--digits >= 0 || value != 0) { - value = Math.DivRem(value, 10, out uint remainder); + value = MathEx.DivRem(value, 10, out uint remainder); *(--bufferEnd) = (byte)(remainder + '0'); } return bufferEnd; @@ -1215,7 +1215,7 @@ private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) { while (--digits >= 0 || value != 0) { - value = Math.DivRem(value, 10, out uint remainder); + value = MathEx.DivRem(value, 10, out uint remainder); *(--bufferEnd) = (char)(remainder + '0'); } return bufferEnd; @@ -1231,7 +1231,7 @@ internal static unsafe string UInt32ToDecStr(uint value, int digits) return s_singleDigitStringCache[value]; } - string result = string.FastAllocateString(bufferLength); + string result = FastAllocateString(bufferLength); fixed (char* buffer = result) { char* p = buffer + bufferLength; @@ -1239,7 +1239,7 @@ internal static unsafe string UInt32ToDecStr(uint value, int digits) { do { - value = Math.DivRem(value, 10, out uint remainder); + value = MathEx.DivRem(value, 10, out uint remainder); *(--p) = (char)(remainder + '0'); } while (value != 0); @@ -1270,7 +1270,7 @@ private static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span { do { - value = Math.DivRem(value, 10, out uint remainder); + value = MathEx.DivRem(value, 10, out uint remainder); *(--p) = (char)(remainder + '0'); } while (value != 0); @@ -1325,7 +1325,7 @@ private static unsafe string NegativeInt64ToDecStr(long input, int digits, strin ulong value = (ulong)(-input); int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(value)) + sNegative.Length; - string result = string.FastAllocateString(bufferLength); + string result = FastAllocateString(bufferLength); fixed (char* buffer = result) { char* p = buffer + bufferLength; @@ -1388,7 +1388,7 @@ private static unsafe bool TryNegativeInt64ToDecStr(long input, int digits, stri private static unsafe string Int64ToHexStr(long value, char hexBase, int digits) { int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); - string result = string.FastAllocateString(bufferLength); + string result = FastAllocateString(bufferLength); fixed (char* buffer = result) { char* p = buffer + bufferLength; @@ -1471,7 +1471,7 @@ internal static unsafe string UInt64ToDecStr(ulong value, int digits) return s_singleDigitStringCache[value]; } - string result = string.FastAllocateString(bufferLength); + string result = FastAllocateString(bufferLength); fixed (char* buffer = result) { char* p = buffer + bufferLength; @@ -1710,7 +1710,7 @@ internal static unsafe void NumberToString(ref ValueStringBuilder sb, ref Number } default: - throw new FormatException(SR.Argument_BadFormatSpecifier); + throw new FormatException("SR.Argument_BadFormatSpecifier"); } } @@ -1884,7 +1884,7 @@ internal static unsafe void NumberToStringFormat(ref ValueStringBuilder sb, ref // The max is not bound since you can have formatting strings of the form "000,000..", and this // should handle that case too. - int[] groupDigits = info._numberGroupSizes; + int[] groupDigits = info.NumberGroupSizes; int groupSizeIndex = 0; // Index into the groupDigits array. int groupTotalSizeCount = 0; @@ -2092,7 +2092,7 @@ private static void FormatCurrency(ref ValueStringBuilder sb, ref NumberBuffer n switch (ch) { case '#': - FormatFixed(ref sb, ref number, nMaxDigits, info._currencyGroupSizes, info.CurrencyDecimalSeparator, info.CurrencyGroupSeparator); + FormatFixed(ref sb, ref number, nMaxDigits, info.CurrencyGroupSizes, info.CurrencyDecimalSeparator, info.CurrencyGroupSeparator); break; case '-': sb.Append(info.NegativeSign); @@ -2222,7 +2222,7 @@ private static void FormatNumber(ref ValueStringBuilder sb, ref NumberBuffer num switch (ch) { case '#': - FormatFixed(ref sb, ref number, nMaxDigits, info._numberGroupSizes, info.NumberDecimalSeparator, info.NumberGroupSeparator); + FormatFixed(ref sb, ref number, nMaxDigits, info.NumberGroupSizes, info.NumberDecimalSeparator, info.NumberGroupSeparator); break; case '-': sb.Append(info.NegativeSign); @@ -2328,7 +2328,7 @@ private static void FormatPercent(ref ValueStringBuilder sb, ref NumberBuffer nu switch (ch) { case '#': - FormatFixed(ref sb, ref number, nMaxDigits, info._percentGroupSizes, info.PercentDecimalSeparator, info.PercentGroupSeparator); + FormatFixed(ref sb, ref number, nMaxDigits, info.PercentGroupSizes, info.PercentDecimalSeparator, info.PercentGroupSeparator); break; case '-': sb.Append(info.NegativeSign); @@ -2535,5 +2535,10 @@ private static uint ExtractFractionAndBiasedExponent(float value, out int expone return fraction; } + + static string FastAllocateString(int length) + { + return new string('\0', length); + } } } \ No newline at end of file diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index dea81e0a..7c249809 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -156,6 +156,9 @@ + + + From bd3d3a0b1f5c4c7fa61aa1ee13a6e84c4d595cac Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Thu, 13 Feb 2020 09:12:46 +0900 Subject: [PATCH 022/139] remove DoubleConversion --- src/ZString/Shims.cs | 216 +++++ src/ZString/Shims/DoubleConversion/DiyFp.cs | 123 --- .../DoubleToStringConverter.cs | 890 ------------------ src/ZString/Shims/DoubleConversion/IEEE.cs | 441 --------- .../DoubleConversion/PowersOfTenCache.cs | 154 --- .../Shims/DoubleConversion/StringToDouble.cs | 535 ----------- .../StringToDoubleConverter.cs | 625 ------------ src/ZString/Shims/Shims.cs | 483 ---------- src/ZString/ZString.csproj | 1 + 9 files changed, 217 insertions(+), 3251 deletions(-) create mode 100644 src/ZString/Shims.cs delete mode 100644 src/ZString/Shims/DoubleConversion/DiyFp.cs delete mode 100644 src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs delete mode 100644 src/ZString/Shims/DoubleConversion/IEEE.cs delete mode 100644 src/ZString/Shims/DoubleConversion/PowersOfTenCache.cs delete mode 100644 src/ZString/Shims/DoubleConversion/StringToDouble.cs delete mode 100644 src/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs delete mode 100644 src/ZString/Shims/Shims.cs diff --git a/src/ZString/Shims.cs b/src/ZString/Shims.cs new file mode 100644 index 00000000..00651657 --- /dev/null +++ b/src/ZString/Shims.cs @@ -0,0 +1,216 @@ +using System; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace Cysharp.Text +{ + internal static class Int32 + { + /// 0 ~ 9 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNumber(char c) + { + return '0' <= c && c <= '9'; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Parse(ReadOnlySpan s) + { + var value = 0L; + var sign = 1; + + if (s[0] == '-') + { + sign = -1; + } + + for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) + { + if (!IsNumber(s[i])) + { + goto END; + } + + // long.MinValue causes overflow so use unchecked. + value = unchecked(value * 10 + ((byte)s[i] - '0')); + } + + END: + return checked((int)(unchecked(value * sign))); + } + } + + internal static class ShimsExtensions + { + public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) + { + if (span.Length == 0) return 0; + fixed (char* src = span) + fixed (byte* dest = bytes) + { + return encoding.GetBytes(src, span.Length, dest, bytes.Length); + } + } + + + + + + + + + public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return Number.TryFormatSingle(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + + public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return Number.TryFormatDouble(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + + public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); + } + else + { + if (value < 0 && format.Length > 0 && (format[0] == 'X' || format[0] == 'x')) + { + uint temp = (uint)(value & 0x000000FF); + return Number.TryFormatUInt32(temp, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return TryWriteUInt64(destination, out charsWritten, value); + } + + static string GetFormat(ReadOnlySpan format) + { + if (format.Length == 0) + { + return null; + } + + return format.ToString(); + } + } +} diff --git a/src/ZString/Shims/DoubleConversion/DiyFp.cs b/src/ZString/Shims/DoubleConversion/DiyFp.cs deleted file mode 100644 index b10835bf..00000000 --- a/src/ZString/Shims/DoubleConversion/DiyFp.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text.Internal -{ - // https://github.com/google/double-conversion/blob/master/double-conversion/diy-fp.cc - // https://github.com/google/double-conversion/blob/master/double-conversion/diy-fp.h - - internal struct DiyFp - { - public const int kSignificandSize = 64; - public const ulong kUint64MSB = 0x8000000000000000; // 0x80000000_00000000; - - // uint64_t f_; - // int e_; - // long f() const { return f_; } - // int e() const { return e_; } - // void set_f(long new_value) { f_ = new_value; } - // void set_e(int new_value) { e_ = new_value; } - - // public field, not safe... - public ulong f; - public int e; - - public DiyFp(ulong significand, int exponent) - { - this.f = significand; - this.e = exponent; - } - - // this = this - other. - // The exponents of both numbers must be the same and the significand of this - // must be bigger than the significand of other. - // The result will not be normalized. - public void Subtract(ref DiyFp other) - { - f -= other.f; - } - - // Returns a - b. - // The exponents of both numbers must be the same and this must be bigger - // than other. The result will not be normalized. - public static DiyFp Minus(ref DiyFp a, ref DiyFp b) - { - DiyFp result = a; - result.Subtract(ref b); - return result; - } - - public static DiyFp operator -(DiyFp lhs, DiyFp rhs) - { - return Minus(ref lhs, ref rhs); - } - - // this = this * other. - public void Multiply(ref DiyFp other) - { - // Simply "emulates" a 128 bit multiplication. - // However: the resulting number only contains 64 bits. The least - // significant 64 bits are only used for rounding the most significant 64 - // bits. - const long kM32 = 0xFFFFFFFFU; - ulong a = f >> 32; - ulong b = f & kM32; - ulong c = other.f >> 32; - ulong d = other.f & kM32; - ulong ac = a * c; - ulong bc = b * c; - ulong ad = a * d; - ulong bd = b * d; - ulong tmp = (bd >> 32) + (ad & kM32) + (bc & kM32); - // By adding 1U << 31 to tmp we round the final result. - // Halfway cases will be round up. - tmp += 1U << 31; - ulong result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); - e += other.e + 64; - f = result_f; - } - - // returns a * b; - public static DiyFp Times(ref DiyFp a, ref DiyFp b) - { - DiyFp result = a; - result.Multiply(ref b); - return result; - } - - public static DiyFp operator *(DiyFp lhs, DiyFp rhs) - { - return Times(ref lhs, ref rhs); - } - - public void Normalize() - { - ulong significand = f; - int exponent = e; - - // This method is mainly called for normalizing boundaries. In general - // boundaries need to be shifted by 10 bits. We thus optimize for this case. - const ulong k10MSBits = 0xFFC0000000000000; // UINT64_2PART_C(0xFFC00000, 00000000); - while ((significand & k10MSBits) == 0) - { - significand <<= 10; - exponent -= 10; - } - while ((significand & kUint64MSB) == 0) - { - significand <<= 1; - exponent--; - } - f = significand; - e = exponent; - } - - public static DiyFp Normalize(ref DiyFp a) - { - DiyFp result = a; - result.Normalize(); - return result; - } - } -} \ No newline at end of file diff --git a/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs b/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs deleted file mode 100644 index 0e398e35..00000000 --- a/src/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs +++ /dev/null @@ -1,890 +0,0 @@ -using System; -using System.Globalization; - -namespace Cysharp.Text.Internal -{ - using uint64_t = System.UInt64; - using uint32_t = System.UInt32; - using System.Collections.Generic; - using System.Text; - - internal ref struct StringBuilder - { - public Span buffer; - public int offset; - - public StringBuilder(Span buffer) - { - this.buffer = buffer; - this.offset = 0; - } - - public bool TryAddCharacter(char str) - { - if (buffer.Length - offset < 1) return false; - buffer[offset++] = str; - return true; - } - - public bool TryAddCharacter(byte str) - { - if (buffer.Length - offset < 1) return false; - buffer[offset++] = (char)str; - return true; - } - - public bool TryAddString(char[] str) - { - if (buffer.Length - offset < str.Length) return false; - for (int i = 0; i < str.Length; i++) - { - buffer[offset + i] = str[i]; - } - offset += str.Length; - return true; - } - - public bool TryAddSubstring(char[] str, int length) - { - if (buffer.Length - offset < length) return false; - for (int i = 0; i < length; i++) - { - buffer[offset + i] = str[i]; - } - offset += length; - return true; - } - - public bool TryAddSubstring(byte[] str, int length) - { - if (buffer.Length - offset < length) return false; - for (int i = 0; i < length; i++) - { - buffer[offset + i] = (char)str[i]; - } - offset += length; - return true; - } - - public bool TryAddSubstring(char[] str, int start, int length) - { - if (buffer.Length - offset < (length - start)) return false; - for (int i = 0; i < length; i++) - { - buffer[offset + i] = str[start + i]; - } - offset += length; - return true; - } - - public bool TryAddSubstring(byte[] str, int start, int length) - { - if (buffer.Length - offset < (length - start)) return false; - for (int i = 0; i < length; i++) - { - buffer[offset + i] = (char)str[start + i]; - } - offset += length; - return true; - } - - public bool TryAddPadding(char c, int count) - { - if (buffer.Length - offset < count) return false; - for (int i = 0; i < count; i++) - { - buffer[offset + i] = c; - } - offset += count; - return true; - } - - public bool TryAddStringSlow(string str) - { - var s = str.AsSpan(); - if (s.TryCopyTo(buffer.Slice(offset))) - { - offset += s.Length; - return true; - } - return false; - } - } - - // C# API - internal static partial class DoubleToStringConverter - { - public static bool TryFormat(Span destination, float value, out int charsWritten) - { - var sb = new StringBuilder(destination); - if (!ToShortestIeeeNumber(value, ref sb, DtoaMode.SHORTEST_SINGLE)) - { - charsWritten = 0; - return false; - } - - charsWritten = sb.offset; - return true; - } - - public static bool TryFormat(Span destination, double value, out int charsWritten) - { - var sb = new StringBuilder(destination); - if (!ToShortestIeeeNumber(value, ref sb, DtoaMode.SHORTEST)) - { - charsWritten = 0; - return false; - } - - charsWritten = sb.offset; - return true; - } - - [ThreadStatic] - static byte[] exponentialRepBuffer; - - [ThreadStatic] - static byte[] decimalRepBuffer; - - static byte[] GetDecimalRepBuffer(int size) - { - if (decimalRepBuffer == null) - { - decimalRepBuffer = new byte[size]; - } - return decimalRepBuffer; - } - - static byte[] GetExponentialRepBuffer(int size) - { - if (exponentialRepBuffer == null) - { - exponentialRepBuffer = new byte[size]; - } - return exponentialRepBuffer; - } - } - - // private porting methods - // https://github.com/google/double-conversion/blob/master/double-conversion/fast-dtoa.h - // https://github.com/google/double-conversion/blob/master/double-conversion/fast-dtoa.cc - - internal static partial class DoubleToStringConverter - { - enum FastDtoaMode - { - // Computes the shortest representation of the given input. The returned - // result will be the most accurate number of this length. Longer - // representations might be more accurate. - FAST_DTOA_SHORTEST, - // Same as FAST_DTOA_SHORTEST but for single-precision floats. - FAST_DTOA_SHORTEST_SINGLE, - // Computes a representation where the precision (number of digits) is - // given as input. The precision is independent of the decimal point. - // FAST_DTOA_PRECISION - }; - - enum DtoaMode - { - SHORTEST, - SHORTEST_SINGLE, - // FIXED, - // PRECISION - } - - enum Flags - { - NO_FLAGS = 0, - EMIT_POSITIVE_EXPONENT_SIGN = 1, - EMIT_TRAILING_DECIMAL_POINT = 2, - EMIT_TRAILING_ZERO_AFTER_POINT = 4, - UNIQUE_ZERO = 8 - }; - - // C# constants - static readonly char[] infinity_symbol_ = double.PositiveInfinity.ToString().ToCharArray(); - static readonly char[] nan_symbol_ = double.NaN.ToString().ToCharArray(); - - // constructor parameter, same as EcmaScriptConverter - //DoubleToStringConverter(int flags, - // const char* infinity_symbol, - // const char* nan_symbol, - // char exponent_character, - // int decimal_in_shortest_low, - // int decimal_in_shortest_high, - // int max_leading_padding_zeroes_in_precision_mode, - // int max_trailing_padding_zeroes_in_precision_mode) - - //const char exponent_character_; - //const int decimal_in_shortest_low_; - //const int decimal_in_shortest_high_; - //const int max_leading_padding_zeroes_in_precision_mode_; - //const int max_trailing_padding_zeroes_in_precision_mode_; - - static readonly Flags flags_ = Flags.UNIQUE_ZERO | Flags.EMIT_POSITIVE_EXPONENT_SIGN; - static readonly char exponent_character_ = 'E'; - static readonly int decimal_in_shortest_low_ = -4; // C# ToString("G") - static readonly int decimal_in_shortest_high_ = 15;// C# ToString("G") - - const int kBase10MaximalLength = 17; - - const int kFastDtoaMaximalLength = 17; - // Same for single-precision numbers. - const int kFastDtoaMaximalSingleLength = 9; - - // The minimal and maximal target exponent define the range of w's binary - // exponent, where 'w' is the result of multiplying the input by a cached power - // of ten. - // - // A different range might be chosen on a different platform, to optimize digit - // generation, but a smaller range requires more powers of ten to be cached. - const int kMinimalTargetExponent = -60; - const int kMaximalTargetExponent = -32; - - // Adjusts the last digit of the generated number, and screens out generated - // solutions that may be inaccurate. A solution may be inaccurate if it is - // outside the safe interval, or if we cannot prove that it is closer to the - // input than a neighboring representation of the same length. - // - // Input: * buffer containing the digits of too_high / 10^kappa - // * the buffer's length - // * distance_too_high_w == (too_high - w).f() * unit - // * unsafe_interval == (too_high - too_low).f() * unit - // * rest = (too_high - buffer * 10^kappa).f() * unit - // * ten_kappa = 10^kappa * unit - // * unit = the common multiplier - // Output: returns true if the buffer is guaranteed to contain the closest - // representable number to the input. - // Modifies the generated digits in the buffer to approach (round towards) w. - static bool RoundWeed(byte[] buffer, - int length, - uint64_t distance_too_high_w, - uint64_t unsafe_interval, - uint64_t rest, - uint64_t ten_kappa, - uint64_t unit) - { - uint64_t small_distance = distance_too_high_w - unit; - uint64_t big_distance = distance_too_high_w + unit; - // Let w_low = too_high - big_distance, and - // w_high = too_high - small_distance. - // Note: w_low < w < w_high - // - // The real w (* unit) must lie somewhere inside the interval - // ]w_low; w_high[ (often written as "(w_low; w_high)") - - // Basically the buffer currently contains a number in the unsafe interval - // ]too_low; too_high[ with too_low < w < too_high - // - // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ^v 1 unit ^ ^ ^ ^ - // boundary_high --------------------- . . . . - // ^v 1 unit . . . . - // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . - // . . ^ . . - // . big_distance . . . - // . . . . rest - // small_distance . . . . - // v . . . . - // w_high - - - - - - - - - - - - - - - - - - . . . . - // ^v 1 unit . . . . - // w ---------------------------------------- . . . . - // ^v 1 unit v . . . - // w_low - - - - - - - - - - - - - - - - - - - - - . . . - // . . v - // buffer --------------------------------------------------+-------+-------- - // . . - // safe_interval . - // v . - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . - // ^v 1 unit . - // boundary_low ------------------------- unsafe_interval - // ^v 1 unit v - // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - // - // Note that the value of buffer could lie anywhere inside the range too_low - // to too_high. - // - // boundary_low, boundary_high and w are approximations of the real boundaries - // and v (the input number). They are guaranteed to be precise up to one unit. - // In fact the error is guaranteed to be strictly less than one unit. - // - // Anything that lies outside the unsafe interval is guaranteed not to round - // to v when read again. - // Anything that lies inside the safe interval is guaranteed to round to v - // when read again. - // If the number inside the buffer lies inside the unsafe interval but not - // inside the safe interval then we simply do not know and bail out (returning - // false). - // - // Similarly we have to take into account the imprecision of 'w' when finding - // the closest representation of 'w'. If we have two potential - // representations, and one is closer to both w_low and w_high, then we know - // it is closer to the actual value v. - // - // By generating the digits of too_high we got the largest (closest to - // too_high) buffer that is still in the unsafe interval. In the case where - // w_high < buffer < too_high we try to decrement the buffer. - // This way the buffer approaches (rounds towards) w. - // There are 3 conditions that stop the decrementation process: - // 1) the buffer is already below w_high - // 2) decrementing the buffer would make it leave the unsafe interval - // 3) decrementing the buffer would yield a number below w_high and farther - // away than the current number. In other words: - // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high - // Instead of using the buffer directly we use its distance to too_high. - // Conceptually rest ~= too_high - buffer - // We need to do the following tests in this order to avoid over- and - // underflows. - while (rest < small_distance && // Negated condition 1 - unsafe_interval - rest >= ten_kappa && // Negated condition 2 - (rest + ten_kappa < small_distance || // buffer{-1} > w_high - small_distance - rest >= rest + ten_kappa - small_distance)) - { - buffer[length - 1]--; - rest += ten_kappa; - } - - // We have approached w+ as much as possible. We now test if approaching w- - // would require changing the buffer. If yes, then we have two possible - // representations close to w, but we cannot decide which one is closer. - if (rest < big_distance && - unsafe_interval - rest >= ten_kappa && - (rest + ten_kappa < big_distance || - big_distance - rest > rest + ten_kappa - big_distance)) - { - return false; - } - - // Weeding test. - // The safe interval is [too_low + 2 ulp; too_high - 2 ulp] - // Since too_low = too_high - unsafe_interval this is equivalent to - // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp] - // Conceptually we have: rest ~= too_high - buffer - return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit); - } - - // Returns the biggest power of ten that is less than or equal to the given - // number. We furthermore receive the maximum number of bits 'number' has. - // - // Returns power == 10^(exponent_plus_one-1) such that - // power <= number < power * 10. - // If number_bits == 0 then 0^(0-1) is returned. - // The number of bits must be <= 32. - // Precondition: number < (1 << (number_bits + 1)). - - // Inspired by the method for finding an integer log base 10 from here: - // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - static readonly uint[] kSmallPowersOfTen = new uint[] { 0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - - static void BiggestPowerTen(uint32_t number, - int number_bits, - out uint32_t power, - out int exponent_plus_one) - { - // 1233/4096 is approximately 1/lg(10). - int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12); - // We increment to skip over the first entry in the kPowersOf10 table. - // Note: kPowersOf10[i] == 10^(i-1). - exponent_plus_one_guess++; - // We don't have any guarantees that 2^number_bits <= number. - if (number < kSmallPowersOfTen[exponent_plus_one_guess]) - { - exponent_plus_one_guess--; - } - power = kSmallPowersOfTen[exponent_plus_one_guess]; - exponent_plus_one = exponent_plus_one_guess; - } - - // Generates the digits of input number w. - // w is a floating-point number (DiyFp), consisting of a significand and an - // exponent. Its exponent is bounded by kMinimalTargetExponent and - // kMaximalTargetExponent. - // Hence -60 <= w.e() <= -32. - // - // Returns false if it fails, in which case the generated digits in the buffer - // should not be used. - // Preconditions: - // * low, w and high are correct up to 1 ulp (unit in the last place). That - // is, their error must be less than a unit of their last digits. - // * low.e() == w.e() == high.e() - // * low < w < high, and taking into account their error: low~ <= high~ - // * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent - // Postconditions: returns false if procedure fails. - // otherwise: - // * buffer is not null-terminated, but len contains the number of digits. - // * buffer contains the shortest possible decimal digit-sequence - // such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the - // correct values of low and high (without their error). - // * if more than one decimal representation gives the minimal number of - // decimal digits then the one closest to W (where W is the correct value - // of w) is chosen. - // Remark: this procedure takes into account the imprecision of its input - // numbers. If the precision is not enough to guarantee all the postconditions - // then false is returned. This usually happens rarely (~0.5%). - // - // Say, for the sake of example, that - // w.e() == -48, and w.f() == 0x1234567890abcdef - // w's value can be computed by w.f() * 2^w.e() - // We can obtain w's integral digits by simply shifting w.f() by -w.e(). - // -> w's integral part is 0x1234 - // w's fractional part is therefore 0x567890abcdef. - // Printing w's integral part is easy (simply print 0x1234 in decimal). - // In order to print its fraction we repeatedly multiply the fraction by 10 and - // get each digit. Example the first digit after the point would be computed by - // (0x567890abcdef * 10) >> 48. -> 3 - // The whole thing becomes slightly more complicated because we want to stop - // once we have enough digits. That is, once the digits inside the buffer - // represent 'w' we can stop. Everything inside the interval low - high - // represents w. However we have to pay attention to low, high and w's - // imprecision. - static bool DigitGen(DiyFp low, - DiyFp w, - DiyFp high, - byte[] buffer, - out int length, - out int kappa) - { - // low, w and high are imprecise, but by less than one ulp (unit in the last - // place). - // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that - // the new numbers are outside of the interval we want the final - // representation to lie in. - // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield - // numbers that are certain to lie in the interval. We will use this fact - // later on. - // We will now start by generating the digits within the uncertain - // interval. Later we will weed out representations that lie outside the safe - // interval and thus _might_ lie outside the correct interval. - uint64_t unit = 1; - DiyFp too_low = new DiyFp(low.f - unit, low.e); - DiyFp too_high = new DiyFp(high.f + unit, high.e); - // too_low and too_high are guaranteed to lie outside the interval we want the - // generated number in. - DiyFp unsafe_interval = DiyFp.Minus(ref too_high, ref too_low); - // We now cut the input number into two parts: the integral digits and the - // fractionals. We will not write any decimal separator though, but adapt - // kappa instead. - // Reminder: we are currently computing the digits (stored inside the buffer) - // such that: too_low < buffer * 10^kappa < too_high - // We use too_high for the digit_generation and stop as soon as possible. - // If we stop early we effectively round down. - DiyFp one = new DiyFp((uint64_t)(1) << -w.e, w.e); - // Division by one is a shift. - uint32_t integrals = (uint32_t)(too_high.f >> -one.e); - // Modulo by one is an and. - uint64_t fractionals = too_high.f & (one.f - 1); - uint32_t divisor; - int divisor_exponent_plus_one; - BiggestPowerTen(integrals, DiyFp.kSignificandSize - (-one.e), - out divisor, out divisor_exponent_plus_one); - kappa = divisor_exponent_plus_one; - length = 0; - // Loop invariant: buffer = too_high / 10^kappa (integer division) - // The invariant holds for the first iteration: kappa has been initialized - // with the divisor exponent + 1. And the divisor is the biggest power of ten - // that is smaller than integrals. - while (kappa > 0) - { - int digit = unchecked((int)(integrals / divisor)); - buffer[length] = (byte)((byte)'0' + digit); - (length)++; - integrals %= divisor; - (kappa)--; - // Note that kappa now equals the exponent of the divisor and that the - // invariant thus holds again. - uint64_t rest = - ((uint64_t)(integrals) << -one.e) + fractionals; - // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e()) - // Reminder: unsafe_interval.e() == one.e() - if (rest < unsafe_interval.f) - { - // Rounding down (by not emitting the remaining digits) yields a number - // that lies within the unsafe interval. - return RoundWeed(buffer, length, DiyFp.Minus(ref too_high, ref w).f, - unsafe_interval.f, rest, - (uint64_t)(divisor) << -one.e, unit); - } - divisor /= 10; - } - - // The integrals have been generated. We are at the point of the decimal - // separator. In the following loop we simply multiply the remaining digits by - // 10 and divide by one. We just need to pay attention to multiply associated - // data (like the interval or 'unit'), too. - // Note that the multiplication by 10 does not overflow, because w.e >= -60 - // and thus one.e >= -60. - for (; ; ) - { - fractionals *= 10; - unit *= 10; - unsafe_interval.f = (unsafe_interval.f * 10); - // Integer division by one. - int digit = (int)(fractionals >> -one.e); - buffer[length] = (byte)((byte)'0' + digit); - (length)++; - fractionals &= one.f - 1; // Modulo by one. - (kappa)--; - if (fractionals < unsafe_interval.f) - { - return RoundWeed(buffer, length, DiyFp.Minus(ref too_high, ref w).f * unit, - unsafe_interval.f, fractionals, one.f, unit); - } - } - } - - // Provides a decimal representation of v. - // Returns true if it succeeds, otherwise the result cannot be trusted. - // There will be *length digits inside the buffer (not null-terminated). - // If the function returns true then - // v == (double) (buffer * 10^decimal_exponent). - // The digits in the buffer are the shortest representation possible: no - // 0.09999999999999999 instead of 0.1. The shorter representation will even be - // chosen even if the longer one would be closer to v. - // The last digit will be closest to the actual v. That is, even if several - // digits might correctly yield 'v' when read again, the closest will be - // computed. - static bool Grisu3(double v, - FastDtoaMode mode, - byte[] buffer, - out int length, - out int decimal_exponent) - { - DiyFp w = new Double(v).AsNormalizedDiyFp(); - // boundary_minus and boundary_plus are the boundaries between v and its - // closest floating-point neighbors. Any number strictly between - // boundary_minus and boundary_plus will round to v when convert to a double. - // Grisu3 will never output representations that lie exactly on a boundary. - DiyFp boundary_minus, boundary_plus; - if (mode == FastDtoaMode.FAST_DTOA_SHORTEST) - { - new Double(v).NormalizedBoundaries(out boundary_minus, out boundary_plus); - } - else if (mode == FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE) - { - float single_v = (float)(v); - new Single(single_v).NormalizedBoundaries(out boundary_minus, out boundary_plus); - } - else - { - throw new Exception("Invalid Mode."); - } - - DiyFp ten_mk; // Cached power of ten: 10^-k - int mk; // -k - int ten_mk_minimal_binary_exponent = - kMinimalTargetExponent - (w.e + DiyFp.kSignificandSize); - int ten_mk_maximal_binary_exponent = - kMaximalTargetExponent - (w.e + DiyFp.kSignificandSize); - PowersOfTenCache.GetCachedPowerForBinaryExponentRange( - ten_mk_minimal_binary_exponent, - ten_mk_maximal_binary_exponent, - out ten_mk, out mk); - - // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a - // 64 bit significand and ten_mk is thus only precise up to 64 bits. - - // The DiyFp::Times procedure rounds its result, and ten_mk is approximated - // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now - // off by a small amount. - // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. - // In other words: let f = scaled_w.f() and e = scaled_w.e(), then - // (f-1) * 2^e < w*10^k < (f+1) * 2^e - DiyFp scaled_w = DiyFp.Times(ref w, ref ten_mk); - - // In theory it would be possible to avoid some recomputations by computing - // the difference between w and boundary_minus/plus (a power of 2) and to - // compute scaled_boundary_minus/plus by subtracting/adding from - // scaled_w. However the code becomes much less readable and the speed - // enhancements are not terriffic. - DiyFp scaled_boundary_minus = DiyFp.Times(ref boundary_minus, ref ten_mk); - DiyFp scaled_boundary_plus = DiyFp.Times(ref boundary_plus, ref ten_mk); - - // DigitGen will generate the digits of scaled_w. Therefore we have - // v == (double) (scaled_w * 10^-mk). - // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an - // integer than it will be updated. For instance if scaled_w == 1.23 then - // the buffer will be filled with "123" und the decimal_exponent will be - // decreased by 2. - int kappa; - bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, - buffer, out length, out kappa); - decimal_exponent = -mk + kappa; - return result; - } - - static bool FastDtoa(double v, - FastDtoaMode mode, - // int requested_digits, - byte[] buffer, - out int length, - out int decimal_point) - { - bool result = false; - int decimal_exponent = 0; - switch (mode) - { - case FastDtoaMode.FAST_DTOA_SHORTEST: - case FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE: - result = Grisu3(v, mode, buffer, out length, out decimal_exponent); - break; - // case FastDtoaMode.FAST_DTOA_PRECISION: - //result = Grisu3Counted(v, requested_digits, buffer, length, &decimal_exponent); - default: - throw new Exception("unreachable code."); - } - if (result) - { - decimal_point = length + decimal_exponent; - } - else - { - decimal_point = -1; - } - return result; - } - - // https://github.com/google/double-conversion/blob/master/double-conversion/double-conversion.cc - - static bool HandleSpecialValues( - double value, - ref StringBuilder result_builder) - { - Double double_inspect = new Double(value); - if (double_inspect.IsInfinite()) - { - if (infinity_symbol_ == null) return false; - if (value < 0) - { - if (!result_builder.TryAddCharacter('-')) return false; - } - if (!result_builder.TryAddString(infinity_symbol_)) return false; - return true; - } - if (double_inspect.IsNan()) - { - if (nan_symbol_ == null) return false; - if (!result_builder.TryAddString(nan_symbol_)) return false; - return true; - } - return false; - } - - static bool ToShortestIeeeNumber( - double value, - ref StringBuilder result_builder, - DtoaMode mode) - { - if (new Double(value).IsSpecial()) - { - return HandleSpecialValues(value, ref result_builder); - } - - int decimal_point; - bool sign; - const int kDecimalRepCapacity = kBase10MaximalLength + 1; - var decimal_rep = GetDecimalRepBuffer(kDecimalRepCapacity); // byte[] decimal_rep = new byte[kDecimalRepCapacity]; - int decimal_rep_length; - - var fastworked = DoubleToAscii(value, mode, 0, decimal_rep, - out sign, out decimal_rep_length, out decimal_point); - - if (!fastworked) - { - // C# custom, slow path - var str = value.ToString("G17", CultureInfo.InvariantCulture); - if (!result_builder.TryAddStringSlow(str)) return false; - return true; - } - - bool unique_zero = (flags_ & Flags.UNIQUE_ZERO) != 0; - if (sign && (value != 0.0 || !unique_zero)) - { - if (!result_builder.TryAddCharacter('-')) return false; - } - - int exponent = decimal_point - 1; - if ((decimal_in_shortest_low_ <= exponent) && - (exponent < decimal_in_shortest_high_)) - { - return CreateDecimalRepresentation(decimal_rep, decimal_rep_length, - decimal_point, - Math.Max(0, decimal_rep_length - decimal_point), - ref result_builder); - } - else - { - return CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, - ref result_builder); - } - } - - static bool CreateDecimalRepresentation( - byte[] decimal_digits, - int length, - int decimal_point, - int digits_after_point, - ref StringBuilder result_builder) - { - // Create a representation that is padded with zeros if needed. - if (decimal_point <= 0) - { - // "0.00000decimal_rep" or "0.000decimal_rep00". - if (!result_builder.TryAddCharacter('0')) return false; - if (digits_after_point > 0) - { - if (!result_builder.TryAddCharacter('.')) return false; - if (!result_builder.TryAddPadding('0', -decimal_point)) return false; - if (!result_builder.TryAddSubstring(decimal_digits, length)) return false; - int remaining_digits = digits_after_point - (-decimal_point) - length; - if (!result_builder.TryAddPadding('0', remaining_digits)) return false; - } - } - else if (decimal_point >= length) - { - // "decimal_rep0000.00000" or "decimal_rep.0000". - if (!result_builder.TryAddSubstring(decimal_digits, length)) return false; - if (!result_builder.TryAddPadding('0', decimal_point - length)) return false; - if (digits_after_point > 0) - { - if (!result_builder.TryAddCharacter('.')) return false; - if (!result_builder.TryAddPadding('0', digits_after_point)) return false; - } - } - else - { - // "decima.l_rep000". - if (!result_builder.TryAddSubstring(decimal_digits, decimal_point)) return false; - if (!result_builder.TryAddCharacter('.')) return false; - if (!result_builder.TryAddSubstring(decimal_digits, decimal_point, length - decimal_point)) return false; - int remaining_digits = digits_after_point - (length - decimal_point); - if (!result_builder.TryAddPadding('0', remaining_digits)) return false; - } - if (digits_after_point == 0) - { - if ((flags_ & Flags.EMIT_TRAILING_DECIMAL_POINT) != 0) - { - if (!result_builder.TryAddCharacter('.')) return false; - } - if ((flags_ & Flags.EMIT_TRAILING_ZERO_AFTER_POINT) != 0) - { - if (!result_builder.TryAddCharacter('0')) return false; - } - } - - return true; - } - - static bool CreateExponentialRepresentation( - byte[] decimal_digits, - int length, - int exponent, - ref StringBuilder result_builder) - { - if (!result_builder.TryAddCharacter(decimal_digits[0])) return false; - if (length != 1) - { - if (!result_builder.TryAddCharacter('.')) return false; - if (!result_builder.TryAddSubstring(decimal_digits, 1, length - 1)) return false; - } - if (!result_builder.TryAddCharacter(exponent_character_)) return false; - if (exponent < 0) - { - if (!result_builder.TryAddCharacter('-')) return false; - exponent = -exponent; - } - else - { - if ((flags_ & Flags.EMIT_POSITIVE_EXPONENT_SIGN) != 0) - { - if (!result_builder.TryAddCharacter('+')) return false; - } - } - if (exponent == 0) - { - if (!result_builder.TryAddCharacter('0')) return false; - return true; - } - const int kMaxExponentLength = 5; - byte[] buffer = GetExponentialRepBuffer(kMaxExponentLength + 1); - buffer[kMaxExponentLength] = (byte)'\0'; - int first_char_pos = kMaxExponentLength; - while (exponent > 0) - { - buffer[--first_char_pos] = (byte)((byte)'0' + (exponent % 10)); - exponent /= 10; - } - if (!result_builder.TryAddSubstring(buffer, first_char_pos, kMaxExponentLength - first_char_pos)) return false; - - return true; - } - - // modified, return fast_worked. - static bool DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - //byte[] buffer, - //int buffer_length, - byte[] vector, // already allocate - out bool sign, - out int length, - out int point) - { - if (new Double(v).Sign() < 0) - { - sign = true; - v = -v; - } - else - { - sign = false; - } - - //if (mode == DtoaMode.PRECISION && requested_digits == 0) - //{ - // vector[0] = '\0'; - // *length = 0; - // return; - //} - - if (v == 0) - { - vector[0] = (byte)'0'; - // vector[1] = '\0'; - length = 1; - point = 1; - return true; - } - - bool fast_worked; - switch (mode) - { - case DtoaMode.SHORTEST: - fast_worked = FastDtoa(v, FastDtoaMode.FAST_DTOA_SHORTEST, vector, out length, out point); - break; - case DtoaMode.SHORTEST_SINGLE: - fast_worked = FastDtoa(v, FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE, vector, out length, out point); - break; - //case FIXED: - // fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); - // break; - //case PRECISION: - // fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, - // vector, length, point); - // break; - default: - fast_worked = false; - throw new Exception("Unreachable code."); - } - // if (fast_worked) return; - - // If the fast dtoa didn't succeed use the slower bignum version. - // BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); - // BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); - // vector[*length] = '\0'; - - return fast_worked; - } - } -} diff --git a/src/ZString/Shims/DoubleConversion/IEEE.cs b/src/ZString/Shims/DoubleConversion/IEEE.cs deleted file mode 100644 index 55bc2fc3..00000000 --- a/src/ZString/Shims/DoubleConversion/IEEE.cs +++ /dev/null @@ -1,441 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Cysharp.Text.Internal -{ - using uint32_t = UInt32; - - [StructLayout(LayoutKind.Explicit, Pack = 1)] - internal struct UnionDoubleULong - { - [FieldOffset(0)] - public double d; - [FieldOffset(0)] - public ulong u64; - } - - [StructLayout(LayoutKind.Explicit, Pack = 1)] - internal struct UnionFloatUInt - { - [FieldOffset(0)] - public float f; - [FieldOffset(0)] - public uint u32; - } - - // https://github.com/google/double-conversion/blob/master/double-conversion/ieee.h - - internal struct Double - { - public const ulong kSignMask = (0x8000000000000000); - public const ulong kExponentMask = (0x7FF0000000000000); - public const ulong kSignificandMask = (0x000FFFFFFFFFFFFF); - public const ulong kHiddenBit = (0x0010000000000000); - public const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. - public const int kSignificandSize = 53; - - const int kExponentBias = 0x3FF + kPhysicalSignificandSize; - const int kDenormalExponent = -kExponentBias + 1; - const int kMaxExponent = 0x7FF - kExponentBias; - const ulong kInfinity = (0x7FF0000000000000); - const ulong kNaN = (0x7FF8000000000000); - - ulong d64_; - - public Double(double d) - { - d64_ = new UnionDoubleULong { d = d }.u64; - } - - public Double(DiyFp d) - { - d64_ = DiyFpToUint64(d); - } - - // The value encoded by this Double must be greater or equal to +0.0. - // It must not be special (infinity, or NaN). - public DiyFp AsDiyFp() - { - return new DiyFp(Significand(), Exponent()); - } - - // The value encoded by this Double must be strictly greater than 0. - public DiyFp AsNormalizedDiyFp() - { - ulong f = Significand(); - int e = Exponent(); - - // The current double could be a denormal. - while ((f & kHiddenBit) == 0) - { - f <<= 1; - e--; - } - // Do the final shifts in one go. - f <<= DiyFp.kSignificandSize - kSignificandSize; - e -= DiyFp.kSignificandSize - kSignificandSize; - return new DiyFp(f, e); - } - - // Returns the double's bit as uint64. - public ulong AsUint64() - { - return d64_; - } - - // Returns the next greater double. Returns +infinity on input +infinity. - public double NextDouble() - { - if (d64_ == kInfinity) return new Double(kInfinity).value(); - if (Sign() < 0 && Significand() == 0) - { - // -0.0 - return 0.0; - } - if (Sign() < 0) - { - return new Double(d64_ - 1).value(); - } - else - { - return new Double(d64_ + 1).value(); - } - } - - public double PreviousDouble() - { - if (d64_ == (kInfinity | kSignMask)) return -Infinity(); - if (Sign() < 0) - { - return new Double(d64_ + 1).value(); - } - else - { - if (Significand() == 0) return -0.0; - return new Double(d64_ - 1).value(); - } - } - - public int Exponent() - { - if (IsDenormal()) return kDenormalExponent; - - ulong d64 = AsUint64(); - int biased_e = - (int)((d64 & kExponentMask) >> kPhysicalSignificandSize); - return biased_e - kExponentBias; - } - - public ulong Significand() - { - ulong d64 = AsUint64(); - ulong significand = d64 & kSignificandMask; - if (!IsDenormal()) - { - return significand + kHiddenBit; - } - else - { - return significand; - } - } - - // Returns true if the double is a denormal. - public bool IsDenormal() - { - ulong d64 = AsUint64(); - return (d64 & kExponentMask) == 0; - } - - // We consider denormals not to be special. - // Hence only Infinity and NaN are special. - public bool IsSpecial() - { - ulong d64 = AsUint64(); - return (d64 & kExponentMask) == kExponentMask; - } - - public bool IsNan() - { - ulong d64 = AsUint64(); - return ((d64 & kExponentMask) == kExponentMask) && - ((d64 & kSignificandMask) != 0); - } - - public bool IsInfinite() - { - ulong d64 = AsUint64(); - return ((d64 & kExponentMask) == kExponentMask) && - ((d64 & kSignificandMask) == 0); - } - - public int Sign() - { - ulong d64 = AsUint64(); - return (d64 & kSignMask) == 0 ? 1 : -1; - } - - // Precondition: the value encoded by this Double must be greater or equal - // than +0.0. - public DiyFp UpperBoundary() - { - return new DiyFp(Significand() * 2 + 1, Exponent() - 1); - } - - // Computes the two boundaries of this. - // The bigger boundary (m_plus) is normalized. The lower boundary has the same - // exponent as m_plus. - // Precondition: the value encoded by this Double must be greater than 0. - public void NormalizedBoundaries(out DiyFp out_m_minus, out DiyFp out_m_plus) - { - DiyFp v = this.AsDiyFp(); - var __ = new DiyFp((v.f << 1) + 1, v.e - 1); - var m_plus = DiyFp.Normalize(ref __); - - DiyFp m_minus; - if (LowerBoundaryIsCloser()) - { - m_minus = new DiyFp((v.f << 2) - 1, v.e - 2); - } - else - { - m_minus = new DiyFp((v.f << 1) - 1, v.e - 1); - } - m_minus.f = m_minus.f << (m_minus.e - m_plus.e); - m_minus.e = (m_plus.e); - out_m_plus = m_plus; - out_m_minus = m_minus; - } - - public bool LowerBoundaryIsCloser() - { - // The boundary is closer if the significand is of the form f == 2^p-1 then - // the lower boundary is closer. - // Think of v = 1000e10 and v- = 9999e9. - // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but - // at a distance of 1e8. - // The only exception is for the smallest normal: the largest denormal is - // at the same distance as its successor. - // Note: denormals have the same exponent as the smallest normals. - bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0); - return physical_significand_is_zero && (Exponent() != kDenormalExponent); - } - - public double value() - { - return new UnionDoubleULong { u64 = d64_ }.d; - } - - // Returns the significand size for a given order of magnitude. - // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude. - // This function returns the number of significant binary digits v will have - // once it's encoded into a double. In almost all cases this is equal to - // kSignificandSize. The only exceptions are denormals. They start with - // leading zeroes and their effective significand-size is hence smaller. - public static int SignificandSizeForOrderOfMagnitude(int order) - { - if (order >= (kDenormalExponent + kSignificandSize)) - { - return kSignificandSize; - } - if (order <= kDenormalExponent) return 0; - return order - kDenormalExponent; - } - - public static double Infinity() - { - return new Double(kInfinity).value(); - } - - public static double NaN() - { - return new Double(kNaN).value(); - } - - public static ulong DiyFpToUint64(DiyFp diy_fp) - { - ulong significand = diy_fp.f; - int exponent = diy_fp.e; - while (significand > kHiddenBit + kSignificandMask) - { - significand >>= 1; - exponent++; - } - if (exponent >= kMaxExponent) - { - return kInfinity; - } - if (exponent < kDenormalExponent) - { - return 0; - } - while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) - { - significand <<= 1; - exponent--; - } - ulong biased_exponent; - if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) - { - biased_exponent = 0; - } - else - { - biased_exponent = (ulong)(exponent + kExponentBias); - } - return (significand & kSignificandMask) | - (biased_exponent << kPhysicalSignificandSize); - } - } - - internal struct Single - { - const int kExponentBias = 0x7F + kPhysicalSignificandSize; - const int kDenormalExponent = -kExponentBias + 1; - const int kMaxExponent = 0xFF - kExponentBias; - const uint32_t kInfinity = 0x7F800000; - const uint32_t kNaN = 0x7FC00000; - - public const uint32_t kSignMask = 0x80000000; - public const uint32_t kExponentMask = 0x7F800000; - public const uint32_t kSignificandMask = 0x007FFFFF; - public const uint32_t kHiddenBit = 0x00800000; - public const int kPhysicalSignificandSize = 23; // Excludes the hidden bit. - public const int kSignificandSize = 24; - - uint32_t d32_; - - public Single(float f) - { - this.d32_ = new UnionFloatUInt { f = f }.u32; - } - - // The value encoded by this Single must be greater or equal to +0.0. - // It must not be special (infinity, or NaN). - public DiyFp AsDiyFp() - { - return new DiyFp(Significand(), Exponent()); - } - - // Returns the single's bit as uint64. - public uint32_t AsUint32() - { - return d32_; - } - - public int Exponent() - { - if (IsDenormal()) return kDenormalExponent; - - uint32_t d32 = AsUint32(); - int biased_e = (int)((d32 & kExponentMask) >> kPhysicalSignificandSize); - return biased_e - kExponentBias; - } - - public uint32_t Significand() - { - uint32_t d32 = AsUint32(); - uint32_t significand = d32 & kSignificandMask; - if (!IsDenormal()) - { - return significand + kHiddenBit; - } - else - { - return significand; - } - } - - // Returns true if the single is a denormal. - public bool IsDenormal() - { - uint32_t d32 = AsUint32(); - return (d32 & kExponentMask) == 0; - } - - // We consider denormals not to be special. - // Hence only Infinity and NaN are special. - public bool IsSpecial() - { - uint32_t d32 = AsUint32(); - return (d32 & kExponentMask) == kExponentMask; - } - - public bool IsNan() - { - uint32_t d32 = AsUint32(); - return ((d32 & kExponentMask) == kExponentMask) && - ((d32 & kSignificandMask) != 0); - } - - public bool IsInfinite() - { - uint32_t d32 = AsUint32(); - return ((d32 & kExponentMask) == kExponentMask) && - ((d32 & kSignificandMask) == 0); - } - - public int Sign() - { - uint32_t d32 = AsUint32(); - return (d32 & kSignMask) == 0 ? 1 : -1; - } - - // Computes the two boundaries of this. - // The bigger boundary (m_plus) is normalized. The lower boundary has the same - // exponent as m_plus. - // Precondition: the value encoded by this Single must be greater than 0. - public void NormalizedBoundaries(out DiyFp out_m_minus, out DiyFp out_m_plus) - { - DiyFp v = this.AsDiyFp(); - var __ = new DiyFp((v.f << 1) + 1, v.e - 1); - DiyFp m_plus = DiyFp.Normalize(ref __); - DiyFp m_minus; - if (LowerBoundaryIsCloser()) - { - m_minus = new DiyFp((v.f << 2) - 1, v.e - 2); - } - else - { - m_minus = new DiyFp((v.f << 1) - 1, v.e - 1); - } - m_minus.f = (m_minus.f << (m_minus.e - m_plus.e)); - m_minus.e = (m_plus.e); - out_m_plus = m_plus; - out_m_minus = m_minus; - } - - // Precondition: the value encoded by this Single must be greater or equal - // than +0.0. - public DiyFp UpperBoundary() - { - return new DiyFp(Significand() * 2 + 1, Exponent() - 1); - } - - public bool LowerBoundaryIsCloser() - { - // The boundary is closer if the significand is of the form f == 2^p-1 then - // the lower boundary is closer. - // Think of v = 1000e10 and v- = 9999e9. - // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but - // at a distance of 1e8. - // The only exception is for the smallest normal: the largest denormal is - // at the same distance as its successor. - // Note: denormals have the same exponent as the smallest normals. - bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0); - return physical_significand_is_zero && (Exponent() != kDenormalExponent); - } - - public float value() { return new UnionFloatUInt { u32 = d32_ }.f; } - - public static float Infinity() - { - return new Single(kInfinity).value(); - } - - public static float NaN() - { - return new Single(kNaN).value(); - } - } -} diff --git a/src/ZString/Shims/DoubleConversion/PowersOfTenCache.cs b/src/ZString/Shims/DoubleConversion/PowersOfTenCache.cs deleted file mode 100644 index 2150d858..00000000 --- a/src/ZString/Shims/DoubleConversion/PowersOfTenCache.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text.Internal -{ - using uint64_t = UInt64; - using int16_t = Int16; - - // https://github.com/google/double-conversion/blob/master/double-conversion/cached-powers.h - // https://github.com/google/double-conversion/blob/master/double-conversion/cached-powers.cc - - internal struct CachedPower - { - public readonly uint64_t significand; - public readonly int16_t binary_exponent; - public readonly int16_t decimal_exponent; - - public CachedPower(ulong significand, short binary_exponent, short decimal_exponent) - { - this.significand = significand; - this.binary_exponent = binary_exponent; - this.decimal_exponent = decimal_exponent; - } - }; - - internal static class PowersOfTenCache - { - static readonly CachedPower[] kCachedPowers = new CachedPower[] - { - new CachedPower (0xfa8fd5a0081c0288, -1220, -348), - new CachedPower (0xbaaee17fa23ebf76, -1193, -340), - new CachedPower (0x8b16fb203055ac76, -1166, -332), - new CachedPower (0xcf42894a5dce35ea, -1140, -324), - new CachedPower (0x9a6bb0aa55653b2d, -1113, -316), - new CachedPower (0xe61acf033d1a45df, -1087, -308), - new CachedPower (0xab70fe17c79ac6ca, -1060, -300), - new CachedPower (0xff77b1fcbebcdc4f, -1034, -292), - new CachedPower (0xbe5691ef416bd60c, -1007, -284), - new CachedPower (0x8dd01fad907ffc3c, -980, -276), - new CachedPower (0xd3515c2831559a83, -954, -268), - new CachedPower (0x9d71ac8fada6c9b5, -927, -260), - new CachedPower (0xea9c227723ee8bcb, -901, -252), - new CachedPower (0xaecc49914078536d, -874, -244), - new CachedPower (0x823c12795db6ce57, -847, -236), - new CachedPower (0xc21094364dfb5637, -821, -228), - new CachedPower (0x9096ea6f3848984f, -794, -220), - new CachedPower (0xd77485cb25823ac7, -768, -212), - new CachedPower (0xa086cfcd97bf97f4, -741, -204), - new CachedPower (0xef340a98172aace5, -715, -196), - new CachedPower (0xb23867fb2a35b28e, -688, -188), - new CachedPower (0x84c8d4dfd2c63f3b, -661, -180), - new CachedPower (0xc5dd44271ad3cdba, -635, -172), - new CachedPower (0x936b9fcebb25c996, -608, -164), - new CachedPower (0xdbac6c247d62a584, -582, -156), - new CachedPower (0xa3ab66580d5fdaf6, -555, -148), - new CachedPower (0xf3e2f893dec3f126, -529, -140), - new CachedPower (0xb5b5ada8aaff80b8, -502, -132), - new CachedPower (0x87625f056c7c4a8b, -475, -124), - new CachedPower (0xc9bcff6034c13053, -449, -116), - new CachedPower (0x964e858c91ba2655, -422, -108), - new CachedPower (0xdff9772470297ebd, -396, -100), - new CachedPower (0xa6dfbd9fb8e5b88f, -369, -92), - new CachedPower (0xf8a95fcf88747d94, -343, -84), - new CachedPower (0xb94470938fa89bcf, -316, -76), - new CachedPower (0x8a08f0f8bf0f156b, -289, -68), - new CachedPower (0xcdb02555653131b6, -263, -60), - new CachedPower (0x993fe2c6d07b7fac, -236, -52), - new CachedPower (0xe45c10c42a2b3b06, -210, -44), - new CachedPower (0xaa242499697392d3, -183, -36), - new CachedPower (0xfd87b5f28300ca0e, -157, -28), - new CachedPower (0xbce5086492111aeb, -130, -20), - new CachedPower (0x8cbccc096f5088cc, -103, -12), - new CachedPower (0xd1b71758e219652c, -77, -4), - new CachedPower (0x9c40000000000000, -50, 4), - new CachedPower (0xe8d4a51000000000, -24, 12), - new CachedPower (0xad78ebc5ac620000, 3, 20), - new CachedPower (0x813f3978f8940984, 30, 28), - new CachedPower (0xc097ce7bc90715b3, 56, 36), - new CachedPower (0x8f7e32ce7bea5c70, 83, 44), - new CachedPower (0xd5d238a4abe98068, 109, 52), - new CachedPower (0x9f4f2726179a2245, 136, 60), - new CachedPower (0xed63a231d4c4fb27, 162, 68), - new CachedPower (0xb0de65388cc8ada8, 189, 76), - new CachedPower (0x83c7088e1aab65db, 216, 84), - new CachedPower (0xc45d1df942711d9a, 242, 92), - new CachedPower (0x924d692ca61be758, 269, 100), - new CachedPower (0xda01ee641a708dea, 295, 108), - new CachedPower (0xa26da3999aef774a, 322, 116), - new CachedPower (0xf209787bb47d6b85, 348, 124), - new CachedPower (0xb454e4a179dd1877, 375, 132), - new CachedPower (0x865b86925b9bc5c2, 402, 140), - new CachedPower (0xc83553c5c8965d3d, 428, 148), - new CachedPower (0x952ab45cfa97a0b3, 455, 156), - new CachedPower (0xde469fbd99a05fe3, 481, 164), - new CachedPower (0xa59bc234db398c25, 508, 172), - new CachedPower (0xf6c69a72a3989f5c, 534, 180), - new CachedPower (0xb7dcbf5354e9bece, 561, 188), - new CachedPower (0x88fcf317f22241e2, 588, 196), - new CachedPower (0xcc20ce9bd35c78a5, 614, 204), - new CachedPower (0x98165af37b2153df, 641, 212), - new CachedPower (0xe2a0b5dc971f303a, 667, 220), - new CachedPower (0xa8d9d1535ce3b396, 694, 228), - new CachedPower (0xfb9b7cd9a4a7443c, 720, 236), - new CachedPower (0xbb764c4ca7a44410, 747, 244), - new CachedPower (0x8bab8eefb6409c1a, 774, 252), - new CachedPower (0xd01fef10a657842c, 800, 260), - new CachedPower (0x9b10a4e5e9913129, 827, 268), - new CachedPower (0xe7109bfba19c0c9d, 853, 276), - new CachedPower (0xac2820d9623bf429, 880, 284), - new CachedPower (0x80444b5e7aa7cf85, 907, 292), - new CachedPower (0xbf21e44003acdd2d, 933, 300), - new CachedPower (0x8e679c2f5e44ff8f, 960, 308), - new CachedPower (0xd433179d9c8cb841, 986, 316), - new CachedPower (0x9e19db92b4e31ba9, 1013, 324), - new CachedPower (0xeb96bf6ebadf77d9, 1039, 332), - new CachedPower (0xaf87023b9bf0ee6b, 1066, 340), - }; - - public const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent. - public const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) - // Difference between the decimal exponents in the table above. - public const int kDecimalExponentDistance = 8; - public const int kMinDecimalExponent = -348; - public const int kMaxDecimalExponent = 340; - - public static void GetCachedPowerForBinaryExponentRange( - int min_exponent, - int max_exponent, - out DiyFp power, - out int decimal_exponent) - { - int kQ = DiyFp.kSignificandSize; - double k = Math.Ceiling((min_exponent + kQ - 1) * kD_1_LOG2_10); - int foo = kCachedPowersOffset; - int index = (foo + (int)(k) - 1) / kDecimalExponentDistance + 1; - - CachedPower cached_power = kCachedPowers[index]; - // (void)max_exponent; // Mark variable as used. - decimal_exponent = cached_power.decimal_exponent; - power = new DiyFp(cached_power.significand, cached_power.binary_exponent); - } - - public static void GetCachedPowerForDecimalExponent(int requested_exponent, - out DiyFp power, - out int found_exponent) - { - int index = (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance; - CachedPower cached_power = kCachedPowers[index]; - power = new DiyFp(cached_power.significand, cached_power.binary_exponent); - found_exponent = cached_power.decimal_exponent; - } - } -} diff --git a/src/ZString/Shims/DoubleConversion/StringToDouble.cs b/src/ZString/Shims/DoubleConversion/StringToDouble.cs deleted file mode 100644 index 0c65eb55..00000000 --- a/src/ZString/Shims/DoubleConversion/StringToDouble.cs +++ /dev/null @@ -1,535 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text.Internal -{ - using uint64_t = UInt64; - - internal struct Vector - { - public readonly byte[] bytes; - public readonly int start; - public readonly int _length; - - public Vector(byte[] bytes, int start, int length) - { - this.bytes = bytes; - this.start = start; - this._length = length; - } - - public byte this[int i] - { - get - { - return bytes[start + i]; - } - set - { - bytes[start + i] = value; - } - } - - public int length() - { - return _length; - } - - public byte first() - { - return bytes[start]; - } - - public byte last() - { - return bytes[_length - 1]; - } - - public bool is_empty() - { - return _length == 0; - } - - public Vector SubVector(int from, int to) - { - return new Vector(this.bytes, start + from, to - from); - } - } - - internal static class StringToDouble - { - [ThreadStatic] - static byte[] copyBuffer; - - static byte[] GetCopyBuffer() - { - if (copyBuffer == null) - { - copyBuffer = new byte[kMaxSignificantDecimalDigits]; - } - return copyBuffer; - } - - // 2^53 = 9007199254740992. - // Any integer with at most 15 decimal digits will hence fit into a double - // (which has a 53bit significand) without loss of precision. - const int kMaxExactDoubleIntegerDecimalDigits = 15; - // 2^64 = 18446744073709551616 > 10^19 - const int kMaxUint64DecimalDigits = 19; - - // Max double: 1.7976931348623157 x 10^308 - // Min non-zero double: 4.9406564584124654 x 10^-324 - // Any x >= 10^309 is interpreted as +infinity. - // Any x <= 10^-324 is interpreted as 0. - // Note that 2.5e-324 (despite being smaller than the min double) will be read - // as non-zero (equal to the min non-zero double). - const int kMaxDecimalPower = 309; - const int kMinDecimalPower = -324; - - // 2^64 = 18446744073709551616 - const uint64_t kMaxUint64 = 0xFFFFFFFFFFFFFFFF; - - static readonly double[] exact_powers_of_ten = new double[]{ - 1.0, // 10^0 - 10.0, - 100.0, - 1000.0, - 10000.0, - 100000.0, - 1000000.0, - 10000000.0, - 100000000.0, - 1000000000.0, - 10000000000.0, // 10^10 - 100000000000.0, - 1000000000000.0, - 10000000000000.0, - 100000000000000.0, - 1000000000000000.0, - 10000000000000000.0, - 100000000000000000.0, - 1000000000000000000.0, - 10000000000000000000.0, - 100000000000000000000.0, // 10^20 - 1000000000000000000000.0, - // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22 - 10000000000000000000000.0 - }; - static readonly int kExactPowersOfTenSize = exact_powers_of_ten.Length; - - // Maximum number of significant digits in the decimal representation. - // In fact the value is 772 (see conversions.cc), but to give us some margin - // we round up to 780. - const int kMaxSignificantDecimalDigits = 780; - - static Vector TrimLeadingZeros(Vector buffer) - { - for (int i = 0; i < buffer.length(); i++) - { - if (buffer[i] != '0') - { - return buffer.SubVector(i, buffer.length()); - } - } - return new Vector(buffer.bytes, buffer.start, 0); - } - - static Vector TrimTrailingZeros(Vector buffer) - { - for (int i = buffer.length() - 1; i >= 0; --i) - { - if (buffer[i] != '0') - { - return buffer.SubVector(0, i + 1); - } - } - return new Vector(buffer.bytes, buffer.start, 0); - } - - - static void CutToMaxSignificantDigits(Vector buffer, - int exponent, - byte[] significant_buffer, - out int significant_exponent) - { - for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) - { - significant_buffer[i] = buffer[i]; - } - // The input buffer has been trimmed. Therefore the last digit must be - // different from '0'. - // ASSERT(buffer[buffer.length() - 1] != '0'); - // Set the last digit to be non-zero. This is sufficient to guarantee - // correct rounding. - significant_buffer[kMaxSignificantDecimalDigits - 1] = (byte)'1'; - significant_exponent = exponent + (buffer.length() - kMaxSignificantDecimalDigits); - } - - // Trims the buffer and cuts it to at most kMaxSignificantDecimalDigits. - // If possible the input-buffer is reused, but if the buffer needs to be - // modified (due to cutting), then the input needs to be copied into the - // buffer_copy_space. - static void TrimAndCut(Vector buffer, int exponent, - byte[] buffer_copy_space, int space_size, - out Vector trimmed, out int updated_exponent) - { - Vector left_trimmed = TrimLeadingZeros(buffer); - Vector right_trimmed = TrimTrailingZeros(left_trimmed); - exponent += left_trimmed.length() - right_trimmed.length(); - if (right_trimmed.length() > kMaxSignificantDecimalDigits) - { - // (void)space_size; // Mark variable as used. - CutToMaxSignificantDigits(right_trimmed, exponent, - buffer_copy_space, out updated_exponent); - trimmed = new Vector(buffer_copy_space, 0, kMaxSignificantDecimalDigits); - } - else - { - trimmed = right_trimmed; - updated_exponent = exponent; - } - } - - - // Reads digits from the buffer and converts them to a uint64. - // Reads in as many digits as fit into a uint64. - // When the string starts with "1844674407370955161" no further digit is read. - // Since 2^64 = 18446744073709551616 it would still be possible read another - // digit if it was less or equal than 6, but this would complicate the code. - static uint64_t ReadUint64(Vector buffer, - out int number_of_read_digits) - { - uint64_t result = 0; - int i = 0; - while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) - { - int digit = buffer[i++] - '0'; - result = 10 * result + (ulong)digit; - } - number_of_read_digits = i; - return result; - } - - // Reads a DiyFp from the buffer. - // The returned DiyFp is not necessarily normalized. - // If remaining_decimals is zero then the returned DiyFp is accurate. - // Otherwise it has been rounded and has error of at most 1/2 ulp. - static void ReadDiyFp(Vector buffer, - out DiyFp result, - out int remaining_decimals) - { - int read_digits; - uint64_t significand = ReadUint64(buffer, out read_digits); - if (buffer.length() == read_digits) - { - result = new DiyFp(significand, 0); - remaining_decimals = 0; - } - else - { - // Round the significand. - if (buffer[read_digits] >= '5') - { - significand++; - } - // Compute the binary exponent. - int exponent = 0; - result = new DiyFp(significand, exponent); - remaining_decimals = buffer.length() - read_digits; - } - } - - - static bool DoubleStrtod(Vector trimmed, - int exponent, - out double result) - { - if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) - { - int read_digits; - // The trimmed input fits into a double. - // If the 10^exponent (resp. 10^-exponent) fits into a double too then we - // can compute the result-double simply by multiplying (resp. dividing) the - // two numbers. - // This is possible because IEEE guarantees that floating-point operations - // return the best possible approximation. - if (exponent < 0 && -exponent < kExactPowersOfTenSize) - { - // 10^-exponent fits into a double. - result = unchecked((double)(ReadUint64(trimmed, out read_digits))); - result /= exact_powers_of_ten[-exponent]; - return true; - } - if (0 <= exponent && exponent < kExactPowersOfTenSize) - { - // 10^exponent fits into a double. - result = unchecked((double)(ReadUint64(trimmed, out read_digits))); - result *= exact_powers_of_ten[exponent]; - return true; - } - int remaining_digits = - kMaxExactDoubleIntegerDecimalDigits - trimmed.length(); - if ((0 <= exponent) && - (exponent - remaining_digits < kExactPowersOfTenSize)) - { - // The trimmed string was short and we can multiply it with - // 10^remaining_digits. As a result the remaining exponent now fits - // into a double too. - result = unchecked((double)(ReadUint64(trimmed, out read_digits))); - result *= exact_powers_of_ten[remaining_digits]; - result *= exact_powers_of_ten[exponent - remaining_digits]; - return true; - } - } - result = 0; - return false; - } - - - // Returns 10^exponent as an exact DiyFp. - // The given exponent must be in the range [1; kDecimalExponentDistance[. - static DiyFp AdjustmentPowerOfTen(int exponent) - { - // Simply hardcode the remaining powers for the given decimal exponent - // distance. - switch (exponent) - { - case 1: return new DiyFp(0xa000000000000000, -60); - case 2: return new DiyFp(0xc800000000000000, -57); - case 3: return new DiyFp(0xfa00000000000000, -54); - case 4: return new DiyFp(0x9c40000000000000, -50); - case 5: return new DiyFp(0xc350000000000000, -47); - case 6: return new DiyFp(0xf424000000000000, -44); - case 7: return new DiyFp(0x9896800000000000, -40); - default: - throw new Exception("unreached code."); - } - } - - // If the function returns true then the result is the correct double. - // Otherwise it is either the correct double or the double that is just below - // the correct double. - static bool DiyFpStrtod(Vector buffer, - int exponent, - out double result) - { - DiyFp input; - int remaining_decimals; - ReadDiyFp(buffer, out input, out remaining_decimals); - // Since we may have dropped some digits the input is not accurate. - // If remaining_decimals is different than 0 than the error is at most - // .5 ulp (unit in the last place). - // We don't want to deal with fractions and therefore keep a common - // denominator. - const int kDenominatorLog = 3; - const int kDenominator = 1 << kDenominatorLog; - // Move the remaining decimals into the exponent. - exponent += remaining_decimals; - uint64_t error = (ulong)(remaining_decimals == 0 ? 0 : kDenominator / 2); - - int old_e = input.e; - input.Normalize(); - error <<= old_e - input.e; - - if (exponent < PowersOfTenCache.kMinDecimalExponent) - { - result = 0.0; - return true; - } - DiyFp cached_power; - int cached_decimal_exponent; - PowersOfTenCache.GetCachedPowerForDecimalExponent(exponent, - out cached_power, - out cached_decimal_exponent); - - if (cached_decimal_exponent != exponent) - { - int adjustment_exponent = exponent - cached_decimal_exponent; - DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent); - input.Multiply(ref adjustment_power); - if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) - { - // The product of input with the adjustment power fits into a 64 bit - // integer. - } - else - { - // The adjustment power is exact. There is hence only an error of 0.5. - error += kDenominator / 2; - } - } - - input.Multiply(ref cached_power); - // The error introduced by a multiplication of a*b equals - // error_a + error_b + error_a*error_b/2^64 + 0.5 - // Substituting a with 'input' and b with 'cached_power' we have - // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp), - // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64 - int error_b = kDenominator / 2; - int error_ab = (error == 0 ? 0 : 1); // We round up to 1. - int fixed_error = kDenominator / 2; - error += (ulong)(error_b + error_ab + fixed_error); - - old_e = input.e; - input.Normalize(); - error <<= old_e - input.e; - - // See if the double's significand changes if we add/subtract the error. - int order_of_magnitude = DiyFp.kSignificandSize + input.e; - int effective_significand_size = Double.SignificandSizeForOrderOfMagnitude(order_of_magnitude); - int precision_digits_count = DiyFp.kSignificandSize - effective_significand_size; - if (precision_digits_count + kDenominatorLog >= DiyFp.kSignificandSize) - { - // This can only happen for very small denormals. In this case the - // half-way multiplied by the denominator exceeds the range of an uint64. - // Simply shift everything to the right. - int shift_amount = (precision_digits_count + kDenominatorLog) - - DiyFp.kSignificandSize + 1; - input.f = (input.f >> shift_amount); - input.e = (input.e + shift_amount); - // We add 1 for the lost precision of error, and kDenominator for - // the lost precision of input.f(). - error = (error >> shift_amount) + 1 + kDenominator; - precision_digits_count -= shift_amount; - } - // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too. - uint64_t one64 = 1; - uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1; - uint64_t precision_bits = input.f & precision_bits_mask; - uint64_t half_way = one64 << (precision_digits_count - 1); - precision_bits *= kDenominator; - half_way *= kDenominator; - DiyFp rounded_input = new DiyFp(input.f >> precision_digits_count, input.e + precision_digits_count); - if (precision_bits >= half_way + error) - { - rounded_input.f = (rounded_input.f + 1); - } - // If the last_bits are too close to the half-way case than we are too - // inaccurate and round down. In this case we return false so that we can - // fall back to a more precise algorithm. - - result = new Double(rounded_input).value(); - if (half_way - error < precision_bits && precision_bits < half_way + error) - { - // Too imprecise. The caller will have to fall back to a slower version. - // However the returned number is guaranteed to be either the correct - // double, or the next-lower double. - return false; - } - else - { - return true; - } - } - - // Returns true if the guess is the correct double. - // Returns false, when guess is either correct or the next-lower double. - static bool ComputeGuess(Vector trimmed, int exponent, - out double guess) - { - if (trimmed.length() == 0) - { - guess = 0.0; - return true; - } - if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) - { - guess = Double.Infinity(); - return true; - } - if (exponent + trimmed.length() <= kMinDecimalPower) - { - guess = 0.0; - return true; - } - - if (DoubleStrtod(trimmed, exponent, out guess) || - DiyFpStrtod(trimmed, exponent, out guess)) - { - return true; - } - if (guess == Double.Infinity()) - { - return true; - } - return false; - } - - public static double? Strtod(Vector buffer, int exponent) - { - byte[] copy_buffer = GetCopyBuffer(); - Vector trimmed; - int updated_exponent; - TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, - out trimmed, out updated_exponent); - exponent = updated_exponent; - - double guess; - var is_correct = ComputeGuess(trimmed, exponent, out guess); - if (is_correct) return guess; - return null; - } - - public static float? Strtof(Vector buffer, int exponent) - { - byte[] copy_buffer = GetCopyBuffer(); - Vector trimmed; - int updated_exponent; - TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, - out trimmed, out updated_exponent); - exponent = updated_exponent; - - double double_guess; - var is_correct = ComputeGuess(trimmed, exponent, out double_guess); - - float float_guess = (float)(double_guess); - if (float_guess == double_guess) - { - // This shortcut triggers for integer values. - return float_guess; - } - - // We must catch double-rounding. Say the double has been rounded up, and is - // now a boundary of a float, and rounds up again. This is why we have to - // look at previous too. - // Example (in decimal numbers): - // input: 12349 - // high-precision (4 digits): 1235 - // low-precision (3 digits): - // when read from input: 123 - // when rounded from high precision: 124. - // To do this we simply look at the neigbors of the correct result and see - // if they would round to the same float. If the guess is not correct we have - // to look at four values (since two different doubles could be the correct - // double). - - double double_next = new Double(double_guess).NextDouble(); - double double_previous = new Double(double_guess).PreviousDouble(); - - float f1 = (float)(double_previous); - // float f2 = float_guess; - float f3 = (float)(double_next); - float f4; - if (is_correct) - { - f4 = f3; - } - else - { - double double_next2 = new Double(double_next).NextDouble(); - f4 = (float)(double_next2); - } - // (void)f2; // Mark variable as used. - - // If the guess doesn't lie near a single-precision boundary we can simply - // return its float-value. - if (f1 == f4) - { - return float_guess; - } - - return null; - } - } -} \ No newline at end of file diff --git a/src/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs b/src/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs deleted file mode 100644 index 67cbe2a1..00000000 --- a/src/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs +++ /dev/null @@ -1,625 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text.Internal -{ -#pragma warning disable 660 -#pragma warning disable 661 - - internal struct Iterator - { - byte[] buffer; - int offset; - - public Iterator(byte[] buffer, int offset) - { - this.buffer = buffer; - this.offset = offset; - } - - public byte Value - { - get - { - return buffer[offset]; - } - } - - public static Iterator operator ++(Iterator self) - { - self.offset++; - return self; - } - - public static Iterator operator +(Iterator self, int length) - { - return new Iterator { buffer = self.buffer, offset = self.offset + length }; - } - - public static int operator -(Iterator lhs, Iterator rhs) - { - return lhs.offset - rhs.offset; - } - - public static bool operator ==(Iterator lhs, Iterator rhs) - { - return lhs.offset == rhs.offset; - } - - public static bool operator !=(Iterator lhs, Iterator rhs) - { - return lhs.offset != rhs.offset; - } - - public static bool operator ==(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] == (byte)rhs; - } - - public static bool operator !=(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] != (byte)rhs; - } - - public static bool operator ==(Iterator lhs, byte rhs) - { - return lhs.buffer[lhs.offset] == (byte)rhs; - } - - public static bool operator !=(Iterator lhs, byte rhs) - { - return lhs.buffer[lhs.offset] != (byte)rhs; - } - - public static bool operator >=(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] >= (byte)rhs; - } - - public static bool operator <=(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] <= (byte)rhs; - } - - public static bool operator >(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] > (byte)rhs; - } - - public static bool operator <(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] < (byte)rhs; - } - } - -#pragma warning restore 661 -#pragma warning restore 660 - - // C# API - internal static partial class StringToDoubleConverter - { - [ThreadStatic] - static byte[] kBuffer; - - static byte[] GetBuffer() - { - if (kBuffer == null) - { - kBuffer = new byte[kBufferSize]; - } - return kBuffer; - } - - [ThreadStatic] - static byte[] fallbackBuffer; - - static byte[] GetFallbackBuffer() - { - if (fallbackBuffer == null) - { - fallbackBuffer = new byte[99]; - } - return fallbackBuffer; - } - - public static double ToDouble(byte[] buffer, int offset, out int readCount) - { - return StringToIeee(new Iterator(buffer, offset), buffer.Length - offset, true, out readCount); - } - - public static float ToSingle(byte[] buffer, int offset, out int readCount) - { - return unchecked((float)StringToIeee(new Iterator(buffer, offset), buffer.Length - offset, false, out readCount)); - } - } - - // port - internal static partial class StringToDoubleConverter - { - enum Flags - { - NO_FLAGS = 0, - ALLOW_HEX = 1, // defined but always disallow - ALLOW_OCTALS = 2, - ALLOW_TRAILING_JUNK = 4, - ALLOW_LEADING_SPACES = 8, - ALLOW_TRAILING_SPACES = 16, - ALLOW_SPACES_AFTER_SIGN = 32, - ALLOW_CASE_INSENSIBILITY = 64, // not supported - }; - - const Flags flags_ = Flags.ALLOW_TRAILING_JUNK | Flags.ALLOW_TRAILING_SPACES | Flags.ALLOW_SPACES_AFTER_SIGN; - const double empty_string_value_ = 0.0; - const double junk_string_value_ = double.NaN; - const int kMaxSignificantDigits = 772; - const int kBufferSize = kMaxSignificantDigits + 10; - static readonly byte[] infinity_symbol_ = Encoding.UTF8.GetBytes(double.PositiveInfinity.ToString()); - static readonly byte[] nan_symbol_ = Encoding.UTF8.GetBytes(double.NaN.ToString()); - - static readonly byte[] kWhitespaceTable7 = new byte[] { 32, 13, 10, 9, 11, 12 }; - static readonly int kWhitespaceTable7Length = kWhitespaceTable7.Length; - - static readonly UInt16[] kWhitespaceTable16 = new UInt16[]{ - 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195, - 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279 - }; - static readonly int kWhitespaceTable16Length = kWhitespaceTable16.Length; - - static bool isWhitespace(int x) - { - if (x < 128) - { - for (int i = 0; i < kWhitespaceTable7Length; i++) - { - if (kWhitespaceTable7[i] == x) return true; - } - } - else - { - for (int i = 0; i < kWhitespaceTable16Length; i++) - { - if (kWhitespaceTable16[i] == x) return true; - } - } - return false; - } - - static bool AdvanceToNonspace(ref Iterator current, Iterator end) - { - while (current != end) - { - if (!isWhitespace(current.Value)) return true; - current++; - } - return false; - } - - static bool ConsumeSubString(ref Iterator current, - Iterator end, - byte[] substring) - { - for (int i = 1; i < substring.Length; i++) - { - ++current; - if (current == end || current != substring[i]) - { - return false; - } - } - ++current; - return true; - } - - - // Consumes first character of the str is equal to ch - static bool ConsumeFirstCharacter(ref Iterator iter, - byte[] str, - int offset) - { - return iter.Value == str[offset]; - } - - static double SignedZero(bool sign) - { - return sign ? -0.0 : 0.0; - } - - static double StringToIeee( - Iterator input, - int length, - bool read_as_double, - out int processed_characters_count) - { - Iterator current = input; - Iterator end = input + length; - - processed_characters_count = 0; - - bool allow_trailing_junk = (flags_ & Flags.ALLOW_TRAILING_JUNK) != 0; - bool allow_leading_spaces = (flags_ & Flags.ALLOW_LEADING_SPACES) != 0; - bool allow_trailing_spaces = (flags_ & Flags.ALLOW_TRAILING_SPACES) != 0; - bool allow_spaces_after_sign = (flags_ & Flags.ALLOW_SPACES_AFTER_SIGN) != 0; - // bool allow_case_insensibility = (flags_ & Flags.ALLOW_CASE_INSENSIBILITY) != 0; - - // To make sure that iterator dereferencing is valid the following - // convention is used: - // 1. Each '++current' statement is followed by check for equality to 'end'. - // 2. If AdvanceToNonspace returned false then current == end. - // 3. If 'current' becomes equal to 'end' the function returns or goes to - // 'parsing_done'. - // 4. 'current' is not dereferenced after the 'parsing_done' label. - // 5. Code before 'parsing_done' may rely on 'current != end'. - if (length == 0) return empty_string_value_; - - if (allow_leading_spaces || allow_trailing_spaces) - { - if (!AdvanceToNonspace(ref current, end)) - { - processed_characters_count = (int)(current - input); - return empty_string_value_; - } - if (!allow_leading_spaces && (input != current)) - { - // No leading spaces allowed, but AdvanceToNonspace moved forward. - return junk_string_value_; - } - } - - // The longest form of simplified number is: "-.1eXXX\0". - byte[] buffer = GetBuffer(); // NOLINT: size is known at compile time. - int buffer_pos = 0; - - // Exponent will be adjusted if insignificant digits of the integer part - // or insignificant leading zeros of the fractional part are dropped. - int exponent = 0; - int significant_digits = 0; - int insignificant_digits = 0; - bool nonzero_digit_dropped = false; - - bool sign = false; - - if (current == '+' || current == '-') - { - sign = (current == '-'); - current++; - Iterator next_non_space = current; - // Skip following spaces (if allowed). - if (!AdvanceToNonspace(ref next_non_space, end)) return junk_string_value_; - if (!allow_spaces_after_sign && (current != next_non_space)) - { - return junk_string_value_; - } - current = next_non_space; - } - - if (infinity_symbol_ != null) - { - if (ConsumeFirstCharacter(ref current, infinity_symbol_, 0)) - { - if (!ConsumeSubString(ref current, end, infinity_symbol_)) - { - return junk_string_value_; - } - - if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) - { - return junk_string_value_; - } - if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) - { - return junk_string_value_; - } - - processed_characters_count = (current - input); - return sign ? double.NegativeInfinity : double.PositiveInfinity; - } - } - - if (nan_symbol_ != null) - { - if (ConsumeFirstCharacter(ref current, nan_symbol_, 0)) - { - if (!ConsumeSubString(ref current, end, nan_symbol_)) - { - return junk_string_value_; - } - - if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) - { - return junk_string_value_; - } - if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) - { - return junk_string_value_; - } - - processed_characters_count = (current - input); - return sign ? -double.NaN : double.NaN; - } - } - - bool leading_zero = false; - if (current == '0') - { - current++; - if (current == end) - { - processed_characters_count = (current - input); - return SignedZero(sign); - } - - leading_zero = true; - - // It could be hexadecimal value. - //if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) - //{ - // ++current; - // if (current == end || !isDigit(*current, 16)) - // { - // return junk_string_value_; // "0x". - // } - - // bool result_is_junk; - // double result = RadixStringToIeee < 4 > (¤t, - // end, - // sign, - // allow_trailing_junk, - // junk_string_value_, - // read_as_double, - // &result_is_junk); - // if (!result_is_junk) - // { - // if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); - // *processed_characters_count = static_cast(current - input); - // } - // return result; - //} - - // Ignore leading zeros in the integer part. - while (current == '0') - { - current++; - if (current == end) - { - processed_characters_count = (current - input); - return SignedZero(sign); - } - } - } - - bool octal = leading_zero && (flags_ & Flags.ALLOW_OCTALS) != 0; - - // Copy significant digits of the integer part (if any) to the buffer. - while (current >= '0' && current <= '9') - { - if (significant_digits < kMaxSignificantDigits) - { - buffer[buffer_pos++] = (current.Value); - significant_digits++; - // Will later check if it's an octal in the buffer. - } - else - { - insignificant_digits++; // Move the digit into the exponential part. - nonzero_digit_dropped = nonzero_digit_dropped || current != '0'; - } - // octal = octal && *current < '8'; - current++; - if (current == end) goto parsing_done; - } - - if (significant_digits == 0) - { - octal = false; - } - - if (current == '.') - { - if (octal && !allow_trailing_junk) return junk_string_value_; - if (octal) goto parsing_done; - - current++; - if (current == end) - { - if (significant_digits == 0 && !leading_zero) - { - return junk_string_value_; - } - else - { - goto parsing_done; - } - } - - if (significant_digits == 0) - { - // octal = false; - // Integer part consists of 0 or is absent. Significant digits start after - // leading zeros (if any). - while (current == '0') - { - ++current; - if (current == end) - { - processed_characters_count = (current - input); - return SignedZero(sign); - } - exponent--; // Move this 0 into the exponent. - } - } - - // There is a fractional part. - // We don't emit a '.', but adjust the exponent instead. - while (current >= '0' && current <= '9') - { - if (significant_digits < kMaxSignificantDigits) - { - buffer[buffer_pos++] = current.Value; - significant_digits++; - exponent--; - } - else - { - // Ignore insignificant digits in the fractional part. - nonzero_digit_dropped = nonzero_digit_dropped || current != '0'; - } - ++current; - if (current == end) goto parsing_done; - } - } - - if (!leading_zero && exponent == 0 && significant_digits == 0) - { - // If leading_zeros is true then the string contains zeros. - // If exponent < 0 then string was [+-]\.0*... - // If significant_digits != 0 the string is not equal to 0. - // Otherwise there are no digits in the string. - return junk_string_value_; - } - - // Parse exponential part. - if (current == 'e' || current == 'E') - { - if (octal && !allow_trailing_junk) return junk_string_value_; - if (octal) goto parsing_done; - ++current; - if (current == end) - { - if (allow_trailing_junk) - { - goto parsing_done; - } - else - { - return junk_string_value_; - } - } - byte exponen_sign = (byte)'+'; - if (current == '+' || current == '-') - { - exponen_sign = current.Value; - ++current; - if (current == end) - { - if (allow_trailing_junk) - { - goto parsing_done; - } - else - { - return junk_string_value_; - } - } - } - - if (current == end || current < '0' || current > '9') - { - if (allow_trailing_junk) - { - goto parsing_done; - } - else - { - return junk_string_value_; - } - } - - const int max_exponent = int.MaxValue / 2; - - int num = 0; - do - { - // Check overflow. - int digit = current.Value - (byte)'0'; - if (num >= max_exponent / 10 - && !(num == max_exponent / 10 && digit <= max_exponent % 10)) - { - num = max_exponent; - } - else - { - num = num * 10 + digit; - } - ++current; - } while (current != end && current >= '0' && current <= '9'); - - exponent += (exponen_sign == '-' ? -num : num); - } - - if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) - { - return junk_string_value_; - } - if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) - { - return junk_string_value_; - } - if (allow_trailing_spaces) - { - AdvanceToNonspace(ref current, end); - } - - parsing_done: - exponent += insignificant_digits; - - //if (octal) - //{ - // double result; - // bool result_is_junk; - // char* start = buffer; - // result = RadixStringToIeee < 3 > (&start, - // buffer + buffer_pos, - // sign, - // allow_trailing_junk, - // junk_string_value_, - // read_as_double, - // &result_is_junk); - // ASSERT(!result_is_junk); - // *processed_characters_count = static_cast(current - input); - // return result; - //} - - if (nonzero_digit_dropped) - { - buffer[buffer_pos++] = (byte)'1'; - exponent--; - } - - buffer[buffer_pos] = (byte)'\0'; - - double? converted; - if (read_as_double) - { - converted = StringToDouble.Strtod(new Vector(buffer, 0, buffer_pos), exponent); - } - else - { - converted = StringToDouble.Strtof(new Vector(buffer, 0, buffer_pos), exponent); - } - - if (converted == null) - { - // read-again - processed_characters_count = (current - input); - - var fallbackbuffer = GetFallbackBuffer(); - if (fallbackBuffer.Length < processed_characters_count) - { - Array.Resize(ref fallbackBuffer, processed_characters_count); - } - var fallbackI = 0; - while (input != current) - { - fallbackbuffer[fallbackI++] = input.Value; - input++; - } - var laststr = Encoding.UTF8.GetString(fallbackbuffer, 0, fallbackI); - return double.Parse(laststr); - } - - processed_characters_count = (current - input); - return sign ? -converted.Value : converted.Value; - } - } -} diff --git a/src/ZString/Shims/Shims.cs b/src/ZString/Shims/Shims.cs deleted file mode 100644 index f6dc0ef3..00000000 --- a/src/ZString/Shims/Shims.cs +++ /dev/null @@ -1,483 +0,0 @@ -using Cysharp.Text.Internal; -using System; -using System.Runtime.CompilerServices; -using System.Text; - -namespace Cysharp.Text -{ - internal static class Int32 - { - /// 0 ~ 9 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsNumber(char c) - { - return '0' <= c && c <= '9'; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Parse(ReadOnlySpan s) - { - var value = 0L; - var sign = 1; - - if (s[0] == '-') - { - sign = -1; - } - - for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) - { - if (!IsNumber(s[i])) - { - goto END; - } - - // long.MinValue causes overflow so use unchecked. - value = unchecked(value * 10 + ((byte)s[i] - '0')); - } - - END: - return checked((int)(unchecked(value * sign))); - } - } - - public static class ShimsExtensions - { - public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) - { - if (span.Length == 0) return 0; - fixed (char* src = span) - fixed (byte* dest = bytes) - { - return encoding.GetBytes(src, span.Length, dest, bytes.Length); - } - } - - public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return DoubleToStringConverter.TryFormat(destination, value, out charsWritten); - } - - public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return DoubleToStringConverter.TryFormat(destination, value, out charsWritten); - } - - public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteUInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteUInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteUInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteUInt64(destination, out charsWritten, value); - } - - static string GetFormat(ReadOnlySpan format) - { - if (format.Length == 0) - { - return null; - } - return format.ToString(); - } - - static bool TryWriteInt64(Span buffer, out int charsWritten, long value) - { - var offset = 0; - charsWritten = 0; - long num1 = value, num2, num3, num4, num5, div; - - if (value < 0) - { - if (value == long.MinValue) // -9223372036854775808 - { - if (buffer.Length < 20) { return false; } - buffer[offset++] = (char)'-'; - buffer[offset++] = (char)'9'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'0'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'6'; - buffer[offset++] = (char)'8'; - buffer[offset++] = (char)'5'; - buffer[offset++] = (char)'4'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'5'; - buffer[offset++] = (char)'8'; - buffer[offset++] = (char)'0'; - buffer[offset++] = (char)'8'; - charsWritten = offset; - return true; - } - - if (buffer.Length < 1) { return false; } - buffer[offset++] = (char)'-'; - num1 = unchecked(-value); - } - - // WriteUInt64(inlined) - - if (num1 < 10000) - { - if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } - if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } - if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } - if (buffer.Length < 4) { return false; } - goto L4; - } - else - { - num2 = num1 / 10000; - num1 -= num2 * 10000; - if (num2 < 10000) - { - if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } - if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } - if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } - if (buffer.Length < 8) { return false; } - goto L8; - } - else - { - num3 = num2 / 10000; - num2 -= num3 * 10000; - if (num3 < 10000) - { - if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } - if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } - if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } - if (buffer.Length < 12) { return false; } - goto L12; - } - else - { - num4 = num3 / 10000; - num3 -= num4 * 10000; - if (num4 < 10000) - { - if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } - if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } - if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } - if (buffer.Length < 16) { return false; } - goto L16; - } - else - { - num5 = num4 / 10000; - num4 -= num5 * 10000; - if (num5 < 10000) - { - if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } - if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } - if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } - if (buffer.Length < 20) { return false; } - goto L20; - } - L20: - buffer[offset++] = (char)('0' + (div = (num5 * 8389L) >> 23)); - num5 -= div * 1000; - L19: - buffer[offset++] = (char)('0' + (div = (num5 * 5243L) >> 19)); - num5 -= div * 100; - L18: - buffer[offset++] = (char)('0' + (div = (num5 * 6554L) >> 16)); - num5 -= div * 10; - L17: - buffer[offset++] = (char)('0' + (num5)); - } - L16: - buffer[offset++] = (char)('0' + (div = (num4 * 8389L) >> 23)); - num4 -= div * 1000; - L15: - buffer[offset++] = (char)('0' + (div = (num4 * 5243L) >> 19)); - num4 -= div * 100; - L14: - buffer[offset++] = (char)('0' + (div = (num4 * 6554L) >> 16)); - num4 -= div * 10; - L13: - buffer[offset++] = (char)('0' + (num4)); - } - L12: - buffer[offset++] = (char)('0' + (div = (num3 * 8389L) >> 23)); - num3 -= div * 1000; - L11: - buffer[offset++] = (char)('0' + (div = (num3 * 5243L) >> 19)); - num3 -= div * 100; - L10: - buffer[offset++] = (char)('0' + (div = (num3 * 6554L) >> 16)); - num3 -= div * 10; - L9: - buffer[offset++] = (char)('0' + (num3)); - } - L8: - buffer[offset++] = (char)('0' + (div = (num2 * 8389L) >> 23)); - num2 -= div * 1000; - L7: - buffer[offset++] = (char)('0' + (div = (num2 * 5243L) >> 19)); - num2 -= div * 100; - L6: - buffer[offset++] = (char)('0' + (div = (num2 * 6554L) >> 16)); - num2 -= div * 10; - L5: - buffer[offset++] = (char)('0' + (num2)); - } - L4: - buffer[offset++] = (char)('0' + (div = (num1 * 8389L) >> 23)); - num1 -= div * 1000; - L3: - buffer[offset++] = (char)('0' + (div = (num1 * 5243L) >> 19)); - num1 -= div * 100; - L2: - buffer[offset++] = (char)('0' + (div = (num1 * 6554L) >> 16)); - num1 -= div * 10; - L1: - buffer[offset++] = (char)('0' + (num1)); - - charsWritten = offset; - return true; - } - - static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) - { - ulong num1 = value, num2, num3, num4, num5, div; - charsWritten = 0; - var offset = 0; - - if (num1 < 10000) - { - if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } - if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } - if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } - if (buffer.Length < 4) { return false; } - goto L4; - } - else - { - num2 = num1 / 10000; - num1 -= num2 * 10000; - if (num2 < 10000) - { - if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } - if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } - if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } - if (buffer.Length < 8) { return false; } - goto L8; - } - else - { - num3 = num2 / 10000; - num2 -= num3 * 10000; - if (num3 < 10000) - { - if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } - if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } - if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } - if (buffer.Length < 12) { return false; } - goto L12; - } - else - { - num4 = num3 / 10000; - num3 -= num4 * 10000; - if (num4 < 10000) - { - if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } - if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } - if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } - if (buffer.Length < 16) { return false; } - goto L16; - } - else - { - num5 = num4 / 10000; - num4 -= num5 * 10000; - if (num5 < 10000) - { - if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } - if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } - if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } - if (buffer.Length < 20) { return false; } - goto L20; - } - L20: - buffer[offset++] = (char)('0' + (div = (num5 * 8389UL) >> 23)); - num5 -= div * 1000; - L19: - buffer[offset++] = (char)('0' + (div = (num5 * 5243UL) >> 19)); - num5 -= div * 100; - L18: - buffer[offset++] = (char)('0' + (div = (num5 * 6554UL) >> 16)); - num5 -= div * 10; - L17: - buffer[offset++] = (char)('0' + (num5)); - } - L16: - buffer[offset++] = (char)('0' + (div = (num4 * 8389UL) >> 23)); - num4 -= div * 1000; - L15: - buffer[offset++] = (char)('0' + (div = (num4 * 5243UL) >> 19)); - num4 -= div * 100; - L14: - buffer[offset++] = (char)('0' + (div = (num4 * 6554UL) >> 16)); - num4 -= div * 10; - L13: - buffer[offset++] = (char)('0' + (num4)); - } - L12: - buffer[offset++] = (char)('0' + (div = (num3 * 8389UL) >> 23)); - num3 -= div * 1000; - L11: - buffer[offset++] = (char)('0' + (div = (num3 * 5243UL) >> 19)); - num3 -= div * 100; - L10: - buffer[offset++] = (char)('0' + (div = (num3 * 6554UL) >> 16)); - num3 -= div * 10; - L9: - buffer[offset++] = (char)('0' + (num3)); - } - L8: - buffer[offset++] = (char)('0' + (div = (num2 * 8389UL) >> 23)); - num2 -= div * 1000; - L7: - buffer[offset++] = (char)('0' + (div = (num2 * 5243UL) >> 19)); - num2 -= div * 100; - L6: - buffer[offset++] = (char)('0' + (div = (num2 * 6554UL) >> 16)); - num2 -= div * 10; - L5: - buffer[offset++] = (char)('0' + (num2)); - } - L4: - buffer[offset++] = (char)('0' + (div = (num1 * 8389UL) >> 23)); - num1 -= div * 1000; - L3: - buffer[offset++] = (char)('0' + (div = (num1 * 5243UL) >> 19)); - num1 -= div * 100; - L2: - buffer[offset++] = (char)('0' + (div = (num1 * 6554UL) >> 16)); - num1 -= div * 10; - L1: - buffer[offset++] = (char)('0' + (num1)); - - charsWritten = offset; - return true; - } - } -} diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 7c249809..3470ddd3 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -158,6 +158,7 @@
+ From 7f43eba69150061f2deb1a61ebbc1dc96f852d37 Mon Sep 17 00:00:00 2001 From: neuecc Date: Thu, 13 Feb 2020 23:13:16 +0900 Subject: [PATCH 023/139] almost complete --- .circleci/config.yml | 16 +- README.md | 118 ++- sandbox/ConsoleApp/ConsoleApp.csproj | 15 +- sandbox/ConsoleApp/Program.cs | 45 +- sandbox/ConsoleAppNet472/Program.cs | 8 +- .../IEEE.cs.meta => FastNumberWriter.cs.meta} | 2 +- .../ZString/{Shims.meta => Number.meta} | 2 +- .../BitOperations.cs.meta} | 2 +- .../BufferEx.cs.meta} | 2 +- .../DecimalEx.cs.meta} | 2 +- .../Scripts/ZString/Number/FloatEx.cs.meta | 11 + .../ZString/Number/FormattingHelpers.cs | 138 +++ .../ZString/Number/FormattingHelpers.cs.meta | 11 + .../Assets/Scripts/ZString/Number/GuidEx.cs | 170 ++++ .../Scripts/ZString/Number/GuidEx.cs.meta | 11 + .../Scripts/ZString/Number/HexConverter.cs | 133 +++ .../ZString/Number/HexConverter.cs.meta | 11 + .../ZString/Number/InternalSpanEx.cs.meta | 11 + .../Scripts/ZString/Number/MathEx.cs.meta | 11 + .../ZString/Number/Number.BigInteger.cs.meta | 11 + .../ZString/Number/Number.DiyFp.cs.meta | 11 + .../ZString/Number/Number.Dragon4.cs.meta | 11 + .../ZString/Number/Number.Formatting.cs.meta | 11 + .../ZString/Number/Number.Grisu3.cs.meta | 11 + .../Number/Number.NumberBuffer.cs.meta | 11 + .../Number.NumberToFloatingPointBits.cs.meta | 11 + .../ZString/Number/Number.Parsing.cs.meta | 11 + .../ZString/Number/NumberFormatInfoEx.cs.meta | 11 + .../ZString/Number/ValueStringBuilder.cs.meta | 11 + .../Assets/Scripts/ZString/Shims.cs | 244 +++++ .../Scripts/ZString/{Shims => }/Shims.cs.meta | 2 +- .../ZString/Shims/DoubleConversion.meta | 8 - .../ZString/Shims/DoubleConversion/DiyFp.cs | 123 --- .../DoubleToStringConverter.cs | 890 ------------------ .../ZString/Shims/DoubleConversion/IEEE.cs | 441 --------- .../DoubleConversion/PowersOfTenCache.cs | 154 --- .../Shims/DoubleConversion/StringToDouble.cs | 535 ----------- .../DoubleConversion/StringToDouble.cs.meta | 11 - .../StringToDoubleConverter.cs | 625 ------------ .../StringToDoubleConverter.cs.meta | 11 - .../Assets/Scripts/ZString/Shims/Shims.cs | 483 ---------- .../TextMeshProExtensions.SetStringBuilder.cs | 14 + .../ZString/Unity/TextMeshProExtensions.cs | 66 +- .../Utf16ValueStringBuilder.AppendFormat.cs | 272 +++--- .../Utf16ValueStringBuilder.Concat.cs.meta | 11 + ...alueStringBuilder.SpanFormattableAppend.cs | 90 +- .../ZString/Utf16ValueStringBuilder.cs | 5 - .../Utf8ValueStringBuilder.AppendFormat.cs | 272 +++--- .../Utf8ValueStringBuilder.Concat.cs.meta | 11 + .../Scripts/ZString/ZString.Concat.cs.meta | 11 + .../Assets/Scripts/ZString/ZString.cs | 9 +- src/ZString/Number/GuidEx.cs | 170 ++++ src/ZString/Number/HexConverter.cs | 133 +++ src/ZString/Shims.cs | 108 ++- src/ZString/Unity/TextMeshProExtensions.cs | 66 +- src/ZString/Unity/TextMeshProExtensions.tt | 3 +- .../Utf16ValueStringBuilder.AppendFormat.cs | 272 +++--- .../Utf16ValueStringBuilder.AppendFormat.tt | 2 +- ...alueStringBuilder.SpanFormattableAppend.cs | 90 +- ...alueStringBuilder.SpanFormattableAppend.tt | 6 +- src/ZString/Utf16ValueStringBuilder.cs | 21 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 272 +++--- .../Utf8ValueStringBuilder.AppendFormat.tt | 2 +- src/ZString/Utf8ValueStringBuilder.cs | 18 +- src/ZString/ZString.cs | 51 +- src/ZString/ZString.csproj | 40 +- .../ZString.NetCore2Tests.csproj | 1 + tests/ZString.Tests/FormatTest.cs | 4 - tests/ZString.Tests/JoinTest.cs | 37 + 69 files changed, 2273 insertions(+), 4140 deletions(-) rename src/ZString.Unity/Assets/Scripts/ZString/{Shims/DoubleConversion/IEEE.cs.meta => FastNumberWriter.cs.meta} (83%) rename src/ZString.Unity/Assets/Scripts/ZString/{Shims.meta => Number.meta} (77%) rename src/ZString.Unity/Assets/Scripts/ZString/{Shims/DoubleConversion/PowersOfTenCache.cs.meta => Number/BitOperations.cs.meta} (83%) rename src/ZString.Unity/Assets/Scripts/ZString/{Shims/DoubleConversion/DoubleToStringConverter.cs.meta => Number/BufferEx.cs.meta} (83%) rename src/ZString.Unity/Assets/Scripts/ZString/{Shims/DoubleConversion/DiyFp.cs.meta => Number/DecimalEx.cs.meta} (83%) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/FloatEx.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/FormattingHelpers.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/FormattingHelpers.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/GuidEx.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/GuidEx.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/HexConverter.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/HexConverter.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/InternalSpanEx.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/MathEx.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.BigInteger.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.DiyFp.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Dragon4.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Formatting.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Grisu3.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberBuffer.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberToFloatingPointBits.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Parsing.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/NumberFormatInfoEx.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Number/ValueStringBuilder.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims.cs rename src/ZString.Unity/Assets/Scripts/ZString/{Shims => }/Shims.cs.meta (83%) delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion.meta delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs.meta delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs.meta delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs.meta create mode 100644 src/ZString/Number/GuidEx.cs create mode 100644 src/ZString/Number/HexConverter.cs create mode 100644 tests/ZString.Tests/JoinTest.cs diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ae4e220..31fb96f2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -46,6 +46,7 @@ jobs: name: unity version: << parameters.unity_version >> steps: + - run: apt update && apt install git -y - checkout - unity_activate: unity_version: << parameters.unity_version >> @@ -96,12 +97,6 @@ workflows: version: 2 default-pipeline: jobs: - - build-unity: - unity_version: 2019.1.2f1 - unity_license: ${UNITY_LICENSE_2019_1} - filters: - tags: - only: /.*/ - build-test: filters: tags: @@ -110,6 +105,14 @@ workflows: # filters: # tags: # only: /.*/ + - build-unity: + unity_version: 2019.1.2f1 + unity_license: ${UNITY_LICENSE_2019_1} + filters: + tags: + only: /^\d\.\d\.\d.*/ + branches: + ignore: /.*/ - build-push: filters: tags: @@ -119,6 +122,7 @@ workflows: - upload-github: requires: - build-unity + - build-push filters: tags: only: /^\d\.\d\.\d.*/ diff --git a/README.md b/README.md index 923be853..b8a87398 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,90 @@ ZString **Z**ero Allocation **String**Builder for .NET Core and Unity. -Currently Preview Release, -0.1.0. +* Struct StringBuilder to avoid allocation of builder itself +* Rent write buffer from `ThreadStatic` or `ArrayPool` +* All append methods are generics(`Append(T value)`) and write to buffer directly instead of concatenate `value.ToString` +* `T0`~`T15` AppendFormat(`AppendFormat(string format, T0 arg0, ..., T15 arg15)` avoids boxing of stuct argument +* Also `T0`~`T15` Concat(`Concat(T0 arg0, ..., T15 arg15)`) avoid boxing and `value.ToString` allocation +* Convinient `ZString.Format/Concat/Join` methods can replace instead of `String.Format/Concat/Join` +* Can use inner buffer to avoid allocate final string +* Can build both Utf16(`Span`) and Utf8(`Span`) directly -Getting Started(Unity, with TextMeshPro) +// ここに性能比較の画像を貼る + +// ここに普通のは何で遅いかの理由を書いておく + +Getting Started --- -Check the [releases](https://github.com/Cysharp/ZString/releases) page, download `ZString.Unity.unitypackage`. +For .NET Core, use NuGet. -```csharp -using Cysharp.Text; // namespace +> PM> Install-Package [ZString](https://www.nuget.org/packages/ZString) -TextMeshProUGUI text; // TMP_Text -int count = 0; +For Unity, check the [releases](https://github.com/Cysharp/ZString/releases) page, download `ZString.Unity.unitypackage`. -void Update() +```csharp +async void Example(int x, int y, int z) { - text.SetTextFormat("Damage: {0}", count++); + // same as x + y + z + _ = ZString.Concat(x, y, z); + + // also can use numeric format strings + _ = ZString.Format("x:{0}, y:{1:000}, z:{2:P}",x, y, z); + + _ = ZString.Join(',', x, y, z); + + // for Unity, direct write(avoid string allocation completely) to TextMeshPro + tmp.SetTextFormat("Position: {0}, {1}, {2}", x, y, z); + + // create StringBuilder + using(var sb = ZString.CreateStringBuilder()) + { + sb.Append("foo"); + sb.AppendLine(42); + sb.AppendFormat("{0} {1:.###}", "bar", 123.456789); + sb.Concat(1, "foo", 100, "bar"); + + // and build final string + var str = sb.ToString(); + + // for Unity, direct write to TextMeshPro + tmp.SetText(sb); + + // write to destination buffer + sb.TryCopyTo(dest, out var written); + } + + // C# 8.0, Using declarations + // create Utf8 StringBuilder that build Utf8 directly to avoid encoding + using var sb2 = ZString.CreateUtf8StringBuilder(); + + sb2.Concat("foo:", x, ", bar:", y); + + // directly write to steam or dest to avoid allocation + await sb2.CopyToAsync(stream); + sb2.TryCopyTo(dest, out var written); } ``` +Reference +--- +ZString + +| method | returns | description | +| -- | -- | -- | +| CreateStringBuilder | Utf16ValueStringBuilder | Create Utf16 string StringBuilder | +| CreateStringBuilder(bool notNested) | Utf16ValueStringBuilder | Create Utf16 string StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | +| CreateUtf8StringBuilder | Utf8ValueStringBuilder | Create Utf8(`Span`) StringBuilder | +| CreateUtf8StringBuilder(bool notNested) | Utf8ValueStringBuilder | Create Utf8(`Span`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | + + +| Join | Utf8ValueStringBuilder | Create Utf8(`Span`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | + + + + + + SetTextFormat is extension method of `TMP_Text`, there parameter is generics so can avoid boxing, and ZString writes to buffer directly without any ToString allocation. Finally inner buffer copy to `TextMeshPro` buffer so avoid all string allocations. ```csharp @@ -48,37 +114,9 @@ using(var sb = ZString.CreateStringBuilder()) var str = ZString.Format("foo {0} bar {1}", 42, 123.456); ``` -Getting Started(.NET Core) ---- - -> PM> Install-Package [ZString](https://www.nuget.org/packages/ZString) - -```csharp -using var sb = ZString.CreateStringBuilder(); - -sb.AppendLine("foo"); -sb.AppendLine(42); -sb.AppendLine("bar"); -sb.AppendLine(123.456); - -Console.WriteLine(sb.ToString()); - -// format, shortform -var str = ZString.Format("foo {0} bar {1}", 42, 123.456); -``` - -```csharp -// write to Utf8 directly -using var sb = ZString.CreateUtf8StringBuilder(); - -sb.AppendLine("foo"); -sb.AppendLine(42); -sb.AppendLine("bar"); -sb.AppendLine(123.456); - -await sb.CopyToAsync(stream); -``` License --- -This library is under the MIT License. +This library is licensed under the the MIT License. + +.NET Standard 2.0 and Unity version borrows [dotnet/runtime](https://github.com/dotnet/runtime) conversion methods, there exists under `ZString/Number` directory. \ No newline at end of file diff --git a/sandbox/ConsoleApp/ConsoleApp.csproj b/sandbox/ConsoleApp/ConsoleApp.csproj index 42d8a9e0..ef582eea 100644 --- a/sandbox/ConsoleApp/ConsoleApp.csproj +++ b/sandbox/ConsoleApp/ConsoleApp.csproj @@ -1,12 +1,13 @@ - - Exe - netcoreapp3.1 - + + Exe + netcoreapp3.1 + - - - + + + + diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index 44d669bc..72e0a97a 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -1,5 +1,8 @@ using Cysharp.Text; using System; +using System.Linq; +using System.Text; +using System.Text.Formatting; namespace ConsoleApp { @@ -12,8 +15,46 @@ static void Main(string[] args) static void Run() { - var s = ZString.Concat("a", 100, "b", 200); - Console.WriteLine(s); + using (var sb = ZString.CreateStringBuilder()) + { + sb.Append("foo"); + sb.AppendLine(42); + sb.AppendFormat("{0} {1:.###}", "bar", 123.456789); + sb.Concat(1, "foo", 100, "bar"); + + Console.WriteLine(sb.ToString()); + } + } + } + + public class FormatBenchmark + { + int x; + int y; + string format; + StringBuilder stringBuilder; + + public FormatBenchmark() + { + x = int.Parse("100"); + y = int.Parse("200"); + format = "x:{0}, y:{1}"; + stringBuilder = new StringBuilder(); + } + + public string StringFormat() + { + return string.Format(format, x, y); + } + + public string ZStringFormat() + { + return ZString.Format(format, x, y); + } + + public string StringFormatterFormat() + { + return StringBuffer.Format(format, x, y); } } } diff --git a/sandbox/ConsoleAppNet472/Program.cs b/sandbox/ConsoleAppNet472/Program.cs index a23a8a2d..6e5be66b 100644 --- a/sandbox/ConsoleAppNet472/Program.cs +++ b/sandbox/ConsoleAppNet472/Program.cs @@ -11,7 +11,13 @@ class Program { static void Main(string[] args) { - + var x = ZString.CreateStringBuilder(); + + x.AppendFormat("hoge{0:.##}, tako{1:000}", 123.456, 9); + Console.WriteLine(x.ToString()); + + var utf7 = ZString.CreateUtf8StringBuilder(); + } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/FastNumberWriter.cs.meta similarity index 83% rename from src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs.meta rename to src/ZString.Unity/Assets/Scripts/ZString/FastNumberWriter.cs.meta index e291edec..9c82a4eb 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/FastNumberWriter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 430f6699b2401fc4a9e70d227c4be60a +guid: dd857f99f11ce484c8a3b600614fd1d3 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number.meta similarity index 77% rename from src/ZString.Unity/Assets/Scripts/ZString/Shims.meta rename to src/ZString.Unity/Assets/Scripts/ZString/Number.meta index 57bbf8df..7d08bede 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ff030f3dccf88234594d248d9d3c845d +guid: 18a14422421519445bb6bd0685394b3b folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/BitOperations.cs.meta similarity index 83% rename from src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs.meta rename to src/ZString.Unity/Assets/Scripts/ZString/Number/BitOperations.cs.meta index fa546e53..20f8d31c 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/BitOperations.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0ceade1a2949e8c4686192afcc6315b5 +guid: 84f68d164ca4db04082e956ba20ee5b4 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/BufferEx.cs.meta similarity index 83% rename from src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs.meta rename to src/ZString.Unity/Assets/Scripts/ZString/Number/BufferEx.cs.meta index 0ef96f87..4d1fe4ce 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/BufferEx.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ee67482db3b18f24f8e0fd7944941e44 +guid: 02503aa3b1ee88741822361d3f10e8b7 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/DecimalEx.cs.meta similarity index 83% rename from src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs.meta rename to src/ZString.Unity/Assets/Scripts/ZString/Number/DecimalEx.cs.meta index 1c5cedb0..e9b80f77 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/DecimalEx.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 88e6d984bcc8a9f449710f9765acf485 +guid: adc39bbd83ade844e9823e44bb8b5445 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/FloatEx.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/FloatEx.cs.meta new file mode 100644 index 00000000..79196459 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/FloatEx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1bfcfb70d615f24fb88dc092457b6c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/FormattingHelpers.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/FormattingHelpers.cs new file mode 100644 index 00000000..7072b315 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/FormattingHelpers.cs @@ -0,0 +1,138 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace System.Buffers.Text +{ + internal static partial class FormattingHelpers + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDigits(ulong value) + { + int digits = 1; + uint part; + if (value >= 10000000) + { + if (value >= 100000000000000) + { + part = (uint)(value / 100000000000000); + digits += 14; + } + else + { + part = (uint)(value / 10000000); + digits += 7; + } + } + else + { + part = (uint)value; + } + + if (part < 10) + { + // no-op + } + else if (part < 100) + { + digits++; + } + else if (part < 1000) + { + digits += 2; + } + else if (part < 10000) + { + digits += 3; + } + else if (part < 100000) + { + digits += 4; + } + else if (part < 1000000) + { + digits += 5; + } + else + { + Debug.Assert(part < 10000000); + digits += 6; + } + + return digits; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDigits(uint value) + { + int digits = 1; + if (value >= 100000) + { + value /= 100000; + digits += 5; + } + + if (value < 10) + { + // no-op + } + else if (value < 100) + { + digits++; + } + else if (value < 1000) + { + digits += 2; + } + else if (value < 10000) + { + digits += 3; + } + else + { + Debug.Assert(value < 100000); + digits += 4; + } + + return digits; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountHexDigits(ulong value) + { + return (64 - BitOperations.LeadingZeroCount(value | 1) + 3) >> 2; + } + + // Counts the number of trailing '0' digits in a decimal number. + // e.g., value = 0 => retVal = 0, valueWithoutTrailingZeros = 0 + // value = 1234 => retVal = 0, valueWithoutTrailingZeros = 1234 + // value = 320900 => retVal = 2, valueWithoutTrailingZeros = 3209 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDecimalTrailingZeros(uint value, out uint valueWithoutTrailingZeros) + { + int zeroCount = 0; + + if (value != 0) + { + while (true) + { + uint temp = value / 10; + if (value != (temp * 10)) + { + break; + } + + value = temp; + zeroCount++; + } + } + + valueWithoutTrailingZeros = value; + return zeroCount; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/FormattingHelpers.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/FormattingHelpers.cs.meta new file mode 100644 index 00000000..f954cbe4 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/FormattingHelpers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e18ceaad90d7f5438604312d93b703b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/GuidEx.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/GuidEx.cs new file mode 100644 index 00000000..7444a5e0 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/GuidEx.cs @@ -0,0 +1,170 @@ +using System.Runtime.InteropServices; + +namespace System +{ + [StructLayout(LayoutKind.Sequential)] + internal struct GuidEx + { + private int _a; // Do not rename (binary serialization) + private short _b; // Do not rename (binary serialization) + private short _c; // Do not rename (binary serialization) + private byte _d; // Do not rename (binary serialization) + private byte _e; // Do not rename (binary serialization) + private byte _f; // Do not rename (binary serialization) + private byte _g; // Do not rename (binary serialization) + private byte _h; // Do not rename (binary serialization) + private byte _i; // Do not rename (binary serialization) + private byte _j; // Do not rename (binary serialization) + private byte _k; // Do not rename (binary serialization) + + private static unsafe int HexsToChars(char* guidChars, int a, int b) + { + guidChars[0] = HexConverter.ToCharLower(a >> 4); + guidChars[1] = HexConverter.ToCharLower(a); + + guidChars[2] = HexConverter.ToCharLower(b >> 4); + guidChars[3] = HexConverter.ToCharLower(b); + + return 4; + } + + private static unsafe int HexsToCharsHexOutput(char* guidChars, int a, int b) + { + guidChars[0] = '0'; + guidChars[1] = 'x'; + + guidChars[2] = HexConverter.ToCharLower(a >> 4); + guidChars[3] = HexConverter.ToCharLower(a); + + guidChars[4] = ','; + guidChars[5] = '0'; + guidChars[6] = 'x'; + + guidChars[7] = HexConverter.ToCharLower(b >> 4); + guidChars[8] = HexConverter.ToCharLower(b); + + return 9; + } + + public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + format = "D".AsSpan(); + } + // all acceptable format strings are of length 1 + if (format.Length != 1) + { + throw new FormatException("InvalidGuidFormatSpecification"); + } + + bool dash = true; + bool hex = false; + int braces = 0; + + int guidSize; + + switch (format[0]) + { + case 'D': + case 'd': + guidSize = 36; + break; + case 'N': + case 'n': + dash = false; + guidSize = 32; + break; + case 'B': + case 'b': + braces = '{' + ('}' << 16); + guidSize = 38; + break; + case 'P': + case 'p': + braces = '(' + (')' << 16); + guidSize = 38; + break; + case 'X': + case 'x': + braces = '{' + ('}' << 16); + dash = false; + hex = true; + guidSize = 68; + break; + default: + throw new FormatException("InvalidGuidFormatSpecification"); + } + + if (destination.Length < guidSize) + { + charsWritten = 0; + return false; + } + + unsafe + { + fixed (char* guidChars = &MemoryMarshal.GetReference(destination)) + { + char* p = guidChars; + + if (braces != 0) + *p++ = (char)braces; + + if (hex) + { + // {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}} + *p++ = '0'; + *p++ = 'x'; + p += HexsToChars(p, _a >> 24, _a >> 16); + p += HexsToChars(p, _a >> 8, _a); + *p++ = ','; + *p++ = '0'; + *p++ = 'x'; + p += HexsToChars(p, _b >> 8, _b); + *p++ = ','; + *p++ = '0'; + *p++ = 'x'; + p += HexsToChars(p, _c >> 8, _c); + *p++ = ','; + *p++ = '{'; + p += HexsToCharsHexOutput(p, _d, _e); + *p++ = ','; + p += HexsToCharsHexOutput(p, _f, _g); + *p++ = ','; + p += HexsToCharsHexOutput(p, _h, _i); + *p++ = ','; + p += HexsToCharsHexOutput(p, _j, _k); + *p++ = '}'; + } + else + { + // [{|(]dddddddd[-]dddd[-]dddd[-]dddd[-]dddddddddddd[}|)] + p += HexsToChars(p, _a >> 24, _a >> 16); + p += HexsToChars(p, _a >> 8, _a); + if (dash) + *p++ = '-'; + p += HexsToChars(p, _b >> 8, _b); + if (dash) + *p++ = '-'; + p += HexsToChars(p, _c >> 8, _c); + if (dash) + *p++ = '-'; + p += HexsToChars(p, _d, _e); + if (dash) + *p++ = '-'; + p += HexsToChars(p, _f, _g); + p += HexsToChars(p, _h, _i); + p += HexsToChars(p, _j, _k); + } + + if (braces != 0) + *p++ = (char)(braces >> 16); + } + } + + charsWritten = guidSize; + return true; + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/GuidEx.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/GuidEx.cs.meta new file mode 100644 index 00000000..3ea64d25 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/GuidEx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1b4d23acb4f60434ea9257c7cc2a1815 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/HexConverter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Number/HexConverter.cs new file mode 100644 index 00000000..4e4e3a72 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/HexConverter.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +namespace System +{ + internal static class HexConverter + { + public enum Casing : uint + { + // Output [ '0' .. '9' ] and [ 'A' .. 'F' ]. + Upper = 0, + + // Output [ '0' .. '9' ] and [ 'a' .. 'f' ]. + // This works because values in the range [ 0x30 .. 0x39 ] ([ '0' .. '9' ]) + // already have the 0x20 bit set, so ORing them with 0x20 is a no-op, + // while outputs in the range [ 0x41 .. 0x46 ] ([ 'A' .. 'F' ]) + // don't have the 0x20 bit set, so ORing them maps to + // [ 0x61 .. 0x66 ] ([ 'a' .. 'f' ]), which is what we want. + Lower = 0x2020U, + } + + // We want to pack the incoming byte into a single integer [ 0000 HHHH 0000 LLLL ], + // where HHHH and LLLL are the high and low nibbles of the incoming byte. Then + // subtract this integer from a constant minuend as shown below. + // + // [ 1000 1001 1000 1001 ] + // - [ 0000 HHHH 0000 LLLL ] + // ========================= + // [ *YYY **** *ZZZ **** ] + // + // The end result of this is that YYY is 0b000 if HHHH <= 9, and YYY is 0b111 if HHHH >= 10. + // Similarly, ZZZ is 0b000 if LLLL <= 9, and ZZZ is 0b111 if LLLL >= 10. + // (We don't care about the value of asterisked bits.) + // + // To turn a nibble in the range [ 0 .. 9 ] into hex, we calculate hex := nibble + 48 (ascii '0'). + // To turn a nibble in the range [ 10 .. 15 ] into hex, we calculate hex := nibble - 10 + 65 (ascii 'A'). + // => hex := nibble + 55. + // The difference in the starting ASCII offset is (55 - 48) = 7, depending on whether the nibble is <= 9 or >= 10. + // Since 7 is 0b111, this conveniently matches the YYY or ZZZ value computed during the earlier subtraction. + + // The commented out code below is code that directly implements the logic described above. + + // uint packedOriginalValues = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU); + // uint difference = 0x8989U - packedOriginalValues; + // uint add7Mask = (difference & 0x7070U) >> 4; // line YYY and ZZZ back up with the packed values + // uint packedResult = packedOriginalValues + add7Mask + 0x3030U /* ascii '0' */; + + // The code below is equivalent to the commented out code above but has been tweaked + // to allow codegen to make some extra optimizations. + + // The low byte of the packed result contains the hex representation of the incoming byte's low nibble. + // The adjacent byte of the packed result contains the hex representation of the incoming byte's high nibble. + + // Finally, write to the output buffer starting with the *highest* index so that codegen can + // elide all but the first bounds check. (This only works if 'startingIndex' is a compile-time constant.) + + // The JIT can elide bounds checks if 'startingIndex' is constant and if the caller is + // writing to a span of known length (or the caller has already checked the bounds of the + // furthest access). + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ToBytesBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) + { + uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; + uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; + + buffer[startingIndex + 1] = (byte)packedResult; + buffer[startingIndex] = (byte)(packedResult >> 8); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ToCharsBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) + { + uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; + uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; + + buffer[startingIndex + 1] = (char)(packedResult & 0xFF); + buffer[startingIndex] = (char)(packedResult >> 8); + } + + public static unsafe string ToString(ReadOnlySpan bytes, Casing casing = Casing.Upper) + { + Span result = stackalloc char[0]; + if (bytes.Length > 16) + { + var array = new char[bytes.Length * 2]; + result = array.AsSpan(); + } + else + { + result = stackalloc char[bytes.Length * 2]; + } + + int pos = 0; + foreach (byte b in bytes) + { + ToCharsBuffer(b, result, pos, casing); + pos += 2; + } + return result.ToString(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char ToCharUpper(int value) + { + value &= 0xF; + value += '0'; + + if (value > '9') + { + value += ('A' - ('9' + 1)); + } + + return (char)value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char ToCharLower(int value) + { + value &= 0xF; + value += '0'; + + if (value > '9') + { + value += ('a' - ('9' + 1)); + } + + return (char)value; + } + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/HexConverter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/HexConverter.cs.meta new file mode 100644 index 00000000..6d873d76 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/HexConverter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc55fbf8adb9a284398481db6426b327 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/InternalSpanEx.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/InternalSpanEx.cs.meta new file mode 100644 index 00000000..2a5d4c61 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/InternalSpanEx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35ddb60e00efb154aa26c3d822b656eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/MathEx.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/MathEx.cs.meta new file mode 100644 index 00000000..224255b0 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/MathEx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b74132cfedcf0e428e2b0760181072f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.BigInteger.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.BigInteger.cs.meta new file mode 100644 index 00000000..e4bf867f --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.BigInteger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ee7ab6f12adee945a329388c6efd7cb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.DiyFp.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.DiyFp.cs.meta new file mode 100644 index 00000000..240645de --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.DiyFp.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 18a3c3c91bd4899498562233c482e696 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Dragon4.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Dragon4.cs.meta new file mode 100644 index 00000000..6b50e876 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Dragon4.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c85d12eb4f5572c45baa13de29cee602 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Formatting.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Formatting.cs.meta new file mode 100644 index 00000000..5fec6865 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Formatting.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5424f58089802e74383c0f5c73ef3e33 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Grisu3.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Grisu3.cs.meta new file mode 100644 index 00000000..3fa3f024 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Grisu3.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5447d418e8d20414f941dc0316a0af97 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberBuffer.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberBuffer.cs.meta new file mode 100644 index 00000000..f0209ca2 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberBuffer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 87bdf9f8d442e2842b3821eea6b35164 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberToFloatingPointBits.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberToFloatingPointBits.cs.meta new file mode 100644 index 00000000..49f8f238 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.NumberToFloatingPointBits.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73257159620332b4aa8656f1ba5a86b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Parsing.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Parsing.cs.meta new file mode 100644 index 00000000..c8d2b987 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/Number.Parsing.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6559ed9c353778499e24e59333cc89f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/NumberFormatInfoEx.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/NumberFormatInfoEx.cs.meta new file mode 100644 index 00000000..444aba80 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/NumberFormatInfoEx.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0550e632456d8424e8b871651efa0bf2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Number/ValueStringBuilder.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Number/ValueStringBuilder.cs.meta new file mode 100644 index 00000000..771e1834 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Number/ValueStringBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4c5602223bfb1324ba376e5508ae9134 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims.cs new file mode 100644 index 00000000..6dd01f74 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims.cs @@ -0,0 +1,244 @@ +#if !NETSTANDARD2_1 + +using System; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Cysharp.Text +{ + internal static class Int32 + { + /// 0 ~ 9 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsNumber(char c) + { + return '0' <= c && c <= '9'; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Parse(ReadOnlySpan s) + { + var value = 0L; + var sign = 1; + + if (s[0] == '-') + { + sign = -1; + } + + for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) + { + if (!IsNumber(s[i])) + { + goto END; + } + + // long.MinValue causes overflow so use unchecked. + value = unchecked(value * 10 + ((byte)s[i] - '0')); + } + + END: + return checked((int)(unchecked(value * sign))); + } + } + + internal static class ShimsExtensions + { + public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) + { + if (span.Length == 0) return 0; + fixed (char* src = span) + fixed (byte* dest = bytes) + { + return encoding.GetBytes(src, span.Length, dest, bytes.Length); + } + } + + public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return Unsafe.As(ref value).TryFormat(destination, out charsWritten, format); + } + + public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + var f = GetFormat(format); + var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); + if (span.TryCopyTo(destination)) + { + charsWritten = span.Length; + return true; + } + else + { + charsWritten = 0; + return false; + } + } + + public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return Number.TryFormatDecimal(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + + public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return Number.TryFormatSingle(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + + public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + return Number.TryFormatDouble(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + + public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); + } + else + { + if (value < 0 && format.Length > 0 && (format[0] == 'X' || format[0] == 'x')) + { + uint temp = (uint)(value & 0x000000FF); + return Number.TryFormatUInt32(temp, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); + } + else + { + if (value < 0 && format.Length > 0 && (format[0] == 'X' || format[0] == 'x')) + { + uint temp = (uint)(value & 0x0000FFFF); + return Number.TryFormatUInt32(temp, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatInt64(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatUInt64(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + } + + static string GetFormat(ReadOnlySpan format) + { + if (format.Length == 0) + { + return null; + } + + return format.ToString(); + } + } +} + +#endif \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims.cs.meta similarity index 83% rename from src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs.meta rename to src/ZString.Unity/Assets/Scripts/ZString/Shims.cs.meta index 55444f23..ae689b2f 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Shims.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: aeb1b3defff24fe47920fb7d01966e52 +guid: f69d4234282aeb44c988b029e96aaee1 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion.meta deleted file mode 100644 index 296bad38..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2fc8643811380444d807e850929557c0 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs deleted file mode 100644 index b10835bf..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DiyFp.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text.Internal -{ - // https://github.com/google/double-conversion/blob/master/double-conversion/diy-fp.cc - // https://github.com/google/double-conversion/blob/master/double-conversion/diy-fp.h - - internal struct DiyFp - { - public const int kSignificandSize = 64; - public const ulong kUint64MSB = 0x8000000000000000; // 0x80000000_00000000; - - // uint64_t f_; - // int e_; - // long f() const { return f_; } - // int e() const { return e_; } - // void set_f(long new_value) { f_ = new_value; } - // void set_e(int new_value) { e_ = new_value; } - - // public field, not safe... - public ulong f; - public int e; - - public DiyFp(ulong significand, int exponent) - { - this.f = significand; - this.e = exponent; - } - - // this = this - other. - // The exponents of both numbers must be the same and the significand of this - // must be bigger than the significand of other. - // The result will not be normalized. - public void Subtract(ref DiyFp other) - { - f -= other.f; - } - - // Returns a - b. - // The exponents of both numbers must be the same and this must be bigger - // than other. The result will not be normalized. - public static DiyFp Minus(ref DiyFp a, ref DiyFp b) - { - DiyFp result = a; - result.Subtract(ref b); - return result; - } - - public static DiyFp operator -(DiyFp lhs, DiyFp rhs) - { - return Minus(ref lhs, ref rhs); - } - - // this = this * other. - public void Multiply(ref DiyFp other) - { - // Simply "emulates" a 128 bit multiplication. - // However: the resulting number only contains 64 bits. The least - // significant 64 bits are only used for rounding the most significant 64 - // bits. - const long kM32 = 0xFFFFFFFFU; - ulong a = f >> 32; - ulong b = f & kM32; - ulong c = other.f >> 32; - ulong d = other.f & kM32; - ulong ac = a * c; - ulong bc = b * c; - ulong ad = a * d; - ulong bd = b * d; - ulong tmp = (bd >> 32) + (ad & kM32) + (bc & kM32); - // By adding 1U << 31 to tmp we round the final result. - // Halfway cases will be round up. - tmp += 1U << 31; - ulong result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); - e += other.e + 64; - f = result_f; - } - - // returns a * b; - public static DiyFp Times(ref DiyFp a, ref DiyFp b) - { - DiyFp result = a; - result.Multiply(ref b); - return result; - } - - public static DiyFp operator *(DiyFp lhs, DiyFp rhs) - { - return Times(ref lhs, ref rhs); - } - - public void Normalize() - { - ulong significand = f; - int exponent = e; - - // This method is mainly called for normalizing boundaries. In general - // boundaries need to be shifted by 10 bits. We thus optimize for this case. - const ulong k10MSBits = 0xFFC0000000000000; // UINT64_2PART_C(0xFFC00000, 00000000); - while ((significand & k10MSBits) == 0) - { - significand <<= 10; - exponent -= 10; - } - while ((significand & kUint64MSB) == 0) - { - significand <<= 1; - exponent--; - } - f = significand; - e = exponent; - } - - public static DiyFp Normalize(ref DiyFp a) - { - DiyFp result = a; - result.Normalize(); - return result; - } - } -} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs deleted file mode 100644 index 0e398e35..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/DoubleToStringConverter.cs +++ /dev/null @@ -1,890 +0,0 @@ -using System; -using System.Globalization; - -namespace Cysharp.Text.Internal -{ - using uint64_t = System.UInt64; - using uint32_t = System.UInt32; - using System.Collections.Generic; - using System.Text; - - internal ref struct StringBuilder - { - public Span buffer; - public int offset; - - public StringBuilder(Span buffer) - { - this.buffer = buffer; - this.offset = 0; - } - - public bool TryAddCharacter(char str) - { - if (buffer.Length - offset < 1) return false; - buffer[offset++] = str; - return true; - } - - public bool TryAddCharacter(byte str) - { - if (buffer.Length - offset < 1) return false; - buffer[offset++] = (char)str; - return true; - } - - public bool TryAddString(char[] str) - { - if (buffer.Length - offset < str.Length) return false; - for (int i = 0; i < str.Length; i++) - { - buffer[offset + i] = str[i]; - } - offset += str.Length; - return true; - } - - public bool TryAddSubstring(char[] str, int length) - { - if (buffer.Length - offset < length) return false; - for (int i = 0; i < length; i++) - { - buffer[offset + i] = str[i]; - } - offset += length; - return true; - } - - public bool TryAddSubstring(byte[] str, int length) - { - if (buffer.Length - offset < length) return false; - for (int i = 0; i < length; i++) - { - buffer[offset + i] = (char)str[i]; - } - offset += length; - return true; - } - - public bool TryAddSubstring(char[] str, int start, int length) - { - if (buffer.Length - offset < (length - start)) return false; - for (int i = 0; i < length; i++) - { - buffer[offset + i] = str[start + i]; - } - offset += length; - return true; - } - - public bool TryAddSubstring(byte[] str, int start, int length) - { - if (buffer.Length - offset < (length - start)) return false; - for (int i = 0; i < length; i++) - { - buffer[offset + i] = (char)str[start + i]; - } - offset += length; - return true; - } - - public bool TryAddPadding(char c, int count) - { - if (buffer.Length - offset < count) return false; - for (int i = 0; i < count; i++) - { - buffer[offset + i] = c; - } - offset += count; - return true; - } - - public bool TryAddStringSlow(string str) - { - var s = str.AsSpan(); - if (s.TryCopyTo(buffer.Slice(offset))) - { - offset += s.Length; - return true; - } - return false; - } - } - - // C# API - internal static partial class DoubleToStringConverter - { - public static bool TryFormat(Span destination, float value, out int charsWritten) - { - var sb = new StringBuilder(destination); - if (!ToShortestIeeeNumber(value, ref sb, DtoaMode.SHORTEST_SINGLE)) - { - charsWritten = 0; - return false; - } - - charsWritten = sb.offset; - return true; - } - - public static bool TryFormat(Span destination, double value, out int charsWritten) - { - var sb = new StringBuilder(destination); - if (!ToShortestIeeeNumber(value, ref sb, DtoaMode.SHORTEST)) - { - charsWritten = 0; - return false; - } - - charsWritten = sb.offset; - return true; - } - - [ThreadStatic] - static byte[] exponentialRepBuffer; - - [ThreadStatic] - static byte[] decimalRepBuffer; - - static byte[] GetDecimalRepBuffer(int size) - { - if (decimalRepBuffer == null) - { - decimalRepBuffer = new byte[size]; - } - return decimalRepBuffer; - } - - static byte[] GetExponentialRepBuffer(int size) - { - if (exponentialRepBuffer == null) - { - exponentialRepBuffer = new byte[size]; - } - return exponentialRepBuffer; - } - } - - // private porting methods - // https://github.com/google/double-conversion/blob/master/double-conversion/fast-dtoa.h - // https://github.com/google/double-conversion/blob/master/double-conversion/fast-dtoa.cc - - internal static partial class DoubleToStringConverter - { - enum FastDtoaMode - { - // Computes the shortest representation of the given input. The returned - // result will be the most accurate number of this length. Longer - // representations might be more accurate. - FAST_DTOA_SHORTEST, - // Same as FAST_DTOA_SHORTEST but for single-precision floats. - FAST_DTOA_SHORTEST_SINGLE, - // Computes a representation where the precision (number of digits) is - // given as input. The precision is independent of the decimal point. - // FAST_DTOA_PRECISION - }; - - enum DtoaMode - { - SHORTEST, - SHORTEST_SINGLE, - // FIXED, - // PRECISION - } - - enum Flags - { - NO_FLAGS = 0, - EMIT_POSITIVE_EXPONENT_SIGN = 1, - EMIT_TRAILING_DECIMAL_POINT = 2, - EMIT_TRAILING_ZERO_AFTER_POINT = 4, - UNIQUE_ZERO = 8 - }; - - // C# constants - static readonly char[] infinity_symbol_ = double.PositiveInfinity.ToString().ToCharArray(); - static readonly char[] nan_symbol_ = double.NaN.ToString().ToCharArray(); - - // constructor parameter, same as EcmaScriptConverter - //DoubleToStringConverter(int flags, - // const char* infinity_symbol, - // const char* nan_symbol, - // char exponent_character, - // int decimal_in_shortest_low, - // int decimal_in_shortest_high, - // int max_leading_padding_zeroes_in_precision_mode, - // int max_trailing_padding_zeroes_in_precision_mode) - - //const char exponent_character_; - //const int decimal_in_shortest_low_; - //const int decimal_in_shortest_high_; - //const int max_leading_padding_zeroes_in_precision_mode_; - //const int max_trailing_padding_zeroes_in_precision_mode_; - - static readonly Flags flags_ = Flags.UNIQUE_ZERO | Flags.EMIT_POSITIVE_EXPONENT_SIGN; - static readonly char exponent_character_ = 'E'; - static readonly int decimal_in_shortest_low_ = -4; // C# ToString("G") - static readonly int decimal_in_shortest_high_ = 15;// C# ToString("G") - - const int kBase10MaximalLength = 17; - - const int kFastDtoaMaximalLength = 17; - // Same for single-precision numbers. - const int kFastDtoaMaximalSingleLength = 9; - - // The minimal and maximal target exponent define the range of w's binary - // exponent, where 'w' is the result of multiplying the input by a cached power - // of ten. - // - // A different range might be chosen on a different platform, to optimize digit - // generation, but a smaller range requires more powers of ten to be cached. - const int kMinimalTargetExponent = -60; - const int kMaximalTargetExponent = -32; - - // Adjusts the last digit of the generated number, and screens out generated - // solutions that may be inaccurate. A solution may be inaccurate if it is - // outside the safe interval, or if we cannot prove that it is closer to the - // input than a neighboring representation of the same length. - // - // Input: * buffer containing the digits of too_high / 10^kappa - // * the buffer's length - // * distance_too_high_w == (too_high - w).f() * unit - // * unsafe_interval == (too_high - too_low).f() * unit - // * rest = (too_high - buffer * 10^kappa).f() * unit - // * ten_kappa = 10^kappa * unit - // * unit = the common multiplier - // Output: returns true if the buffer is guaranteed to contain the closest - // representable number to the input. - // Modifies the generated digits in the buffer to approach (round towards) w. - static bool RoundWeed(byte[] buffer, - int length, - uint64_t distance_too_high_w, - uint64_t unsafe_interval, - uint64_t rest, - uint64_t ten_kappa, - uint64_t unit) - { - uint64_t small_distance = distance_too_high_w - unit; - uint64_t big_distance = distance_too_high_w + unit; - // Let w_low = too_high - big_distance, and - // w_high = too_high - small_distance. - // Note: w_low < w < w_high - // - // The real w (* unit) must lie somewhere inside the interval - // ]w_low; w_high[ (often written as "(w_low; w_high)") - - // Basically the buffer currently contains a number in the unsafe interval - // ]too_low; too_high[ with too_low < w < too_high - // - // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ^v 1 unit ^ ^ ^ ^ - // boundary_high --------------------- . . . . - // ^v 1 unit . . . . - // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . - // . . ^ . . - // . big_distance . . . - // . . . . rest - // small_distance . . . . - // v . . . . - // w_high - - - - - - - - - - - - - - - - - - . . . . - // ^v 1 unit . . . . - // w ---------------------------------------- . . . . - // ^v 1 unit v . . . - // w_low - - - - - - - - - - - - - - - - - - - - - . . . - // . . v - // buffer --------------------------------------------------+-------+-------- - // . . - // safe_interval . - // v . - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . - // ^v 1 unit . - // boundary_low ------------------------- unsafe_interval - // ^v 1 unit v - // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - // - // Note that the value of buffer could lie anywhere inside the range too_low - // to too_high. - // - // boundary_low, boundary_high and w are approximations of the real boundaries - // and v (the input number). They are guaranteed to be precise up to one unit. - // In fact the error is guaranteed to be strictly less than one unit. - // - // Anything that lies outside the unsafe interval is guaranteed not to round - // to v when read again. - // Anything that lies inside the safe interval is guaranteed to round to v - // when read again. - // If the number inside the buffer lies inside the unsafe interval but not - // inside the safe interval then we simply do not know and bail out (returning - // false). - // - // Similarly we have to take into account the imprecision of 'w' when finding - // the closest representation of 'w'. If we have two potential - // representations, and one is closer to both w_low and w_high, then we know - // it is closer to the actual value v. - // - // By generating the digits of too_high we got the largest (closest to - // too_high) buffer that is still in the unsafe interval. In the case where - // w_high < buffer < too_high we try to decrement the buffer. - // This way the buffer approaches (rounds towards) w. - // There are 3 conditions that stop the decrementation process: - // 1) the buffer is already below w_high - // 2) decrementing the buffer would make it leave the unsafe interval - // 3) decrementing the buffer would yield a number below w_high and farther - // away than the current number. In other words: - // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high - // Instead of using the buffer directly we use its distance to too_high. - // Conceptually rest ~= too_high - buffer - // We need to do the following tests in this order to avoid over- and - // underflows. - while (rest < small_distance && // Negated condition 1 - unsafe_interval - rest >= ten_kappa && // Negated condition 2 - (rest + ten_kappa < small_distance || // buffer{-1} > w_high - small_distance - rest >= rest + ten_kappa - small_distance)) - { - buffer[length - 1]--; - rest += ten_kappa; - } - - // We have approached w+ as much as possible. We now test if approaching w- - // would require changing the buffer. If yes, then we have two possible - // representations close to w, but we cannot decide which one is closer. - if (rest < big_distance && - unsafe_interval - rest >= ten_kappa && - (rest + ten_kappa < big_distance || - big_distance - rest > rest + ten_kappa - big_distance)) - { - return false; - } - - // Weeding test. - // The safe interval is [too_low + 2 ulp; too_high - 2 ulp] - // Since too_low = too_high - unsafe_interval this is equivalent to - // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp] - // Conceptually we have: rest ~= too_high - buffer - return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit); - } - - // Returns the biggest power of ten that is less than or equal to the given - // number. We furthermore receive the maximum number of bits 'number' has. - // - // Returns power == 10^(exponent_plus_one-1) such that - // power <= number < power * 10. - // If number_bits == 0 then 0^(0-1) is returned. - // The number of bits must be <= 32. - // Precondition: number < (1 << (number_bits + 1)). - - // Inspired by the method for finding an integer log base 10 from here: - // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - static readonly uint[] kSmallPowersOfTen = new uint[] { 0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - - static void BiggestPowerTen(uint32_t number, - int number_bits, - out uint32_t power, - out int exponent_plus_one) - { - // 1233/4096 is approximately 1/lg(10). - int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12); - // We increment to skip over the first entry in the kPowersOf10 table. - // Note: kPowersOf10[i] == 10^(i-1). - exponent_plus_one_guess++; - // We don't have any guarantees that 2^number_bits <= number. - if (number < kSmallPowersOfTen[exponent_plus_one_guess]) - { - exponent_plus_one_guess--; - } - power = kSmallPowersOfTen[exponent_plus_one_guess]; - exponent_plus_one = exponent_plus_one_guess; - } - - // Generates the digits of input number w. - // w is a floating-point number (DiyFp), consisting of a significand and an - // exponent. Its exponent is bounded by kMinimalTargetExponent and - // kMaximalTargetExponent. - // Hence -60 <= w.e() <= -32. - // - // Returns false if it fails, in which case the generated digits in the buffer - // should not be used. - // Preconditions: - // * low, w and high are correct up to 1 ulp (unit in the last place). That - // is, their error must be less than a unit of their last digits. - // * low.e() == w.e() == high.e() - // * low < w < high, and taking into account their error: low~ <= high~ - // * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent - // Postconditions: returns false if procedure fails. - // otherwise: - // * buffer is not null-terminated, but len contains the number of digits. - // * buffer contains the shortest possible decimal digit-sequence - // such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the - // correct values of low and high (without their error). - // * if more than one decimal representation gives the minimal number of - // decimal digits then the one closest to W (where W is the correct value - // of w) is chosen. - // Remark: this procedure takes into account the imprecision of its input - // numbers. If the precision is not enough to guarantee all the postconditions - // then false is returned. This usually happens rarely (~0.5%). - // - // Say, for the sake of example, that - // w.e() == -48, and w.f() == 0x1234567890abcdef - // w's value can be computed by w.f() * 2^w.e() - // We can obtain w's integral digits by simply shifting w.f() by -w.e(). - // -> w's integral part is 0x1234 - // w's fractional part is therefore 0x567890abcdef. - // Printing w's integral part is easy (simply print 0x1234 in decimal). - // In order to print its fraction we repeatedly multiply the fraction by 10 and - // get each digit. Example the first digit after the point would be computed by - // (0x567890abcdef * 10) >> 48. -> 3 - // The whole thing becomes slightly more complicated because we want to stop - // once we have enough digits. That is, once the digits inside the buffer - // represent 'w' we can stop. Everything inside the interval low - high - // represents w. However we have to pay attention to low, high and w's - // imprecision. - static bool DigitGen(DiyFp low, - DiyFp w, - DiyFp high, - byte[] buffer, - out int length, - out int kappa) - { - // low, w and high are imprecise, but by less than one ulp (unit in the last - // place). - // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that - // the new numbers are outside of the interval we want the final - // representation to lie in. - // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield - // numbers that are certain to lie in the interval. We will use this fact - // later on. - // We will now start by generating the digits within the uncertain - // interval. Later we will weed out representations that lie outside the safe - // interval and thus _might_ lie outside the correct interval. - uint64_t unit = 1; - DiyFp too_low = new DiyFp(low.f - unit, low.e); - DiyFp too_high = new DiyFp(high.f + unit, high.e); - // too_low and too_high are guaranteed to lie outside the interval we want the - // generated number in. - DiyFp unsafe_interval = DiyFp.Minus(ref too_high, ref too_low); - // We now cut the input number into two parts: the integral digits and the - // fractionals. We will not write any decimal separator though, but adapt - // kappa instead. - // Reminder: we are currently computing the digits (stored inside the buffer) - // such that: too_low < buffer * 10^kappa < too_high - // We use too_high for the digit_generation and stop as soon as possible. - // If we stop early we effectively round down. - DiyFp one = new DiyFp((uint64_t)(1) << -w.e, w.e); - // Division by one is a shift. - uint32_t integrals = (uint32_t)(too_high.f >> -one.e); - // Modulo by one is an and. - uint64_t fractionals = too_high.f & (one.f - 1); - uint32_t divisor; - int divisor_exponent_plus_one; - BiggestPowerTen(integrals, DiyFp.kSignificandSize - (-one.e), - out divisor, out divisor_exponent_plus_one); - kappa = divisor_exponent_plus_one; - length = 0; - // Loop invariant: buffer = too_high / 10^kappa (integer division) - // The invariant holds for the first iteration: kappa has been initialized - // with the divisor exponent + 1. And the divisor is the biggest power of ten - // that is smaller than integrals. - while (kappa > 0) - { - int digit = unchecked((int)(integrals / divisor)); - buffer[length] = (byte)((byte)'0' + digit); - (length)++; - integrals %= divisor; - (kappa)--; - // Note that kappa now equals the exponent of the divisor and that the - // invariant thus holds again. - uint64_t rest = - ((uint64_t)(integrals) << -one.e) + fractionals; - // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e()) - // Reminder: unsafe_interval.e() == one.e() - if (rest < unsafe_interval.f) - { - // Rounding down (by not emitting the remaining digits) yields a number - // that lies within the unsafe interval. - return RoundWeed(buffer, length, DiyFp.Minus(ref too_high, ref w).f, - unsafe_interval.f, rest, - (uint64_t)(divisor) << -one.e, unit); - } - divisor /= 10; - } - - // The integrals have been generated. We are at the point of the decimal - // separator. In the following loop we simply multiply the remaining digits by - // 10 and divide by one. We just need to pay attention to multiply associated - // data (like the interval or 'unit'), too. - // Note that the multiplication by 10 does not overflow, because w.e >= -60 - // and thus one.e >= -60. - for (; ; ) - { - fractionals *= 10; - unit *= 10; - unsafe_interval.f = (unsafe_interval.f * 10); - // Integer division by one. - int digit = (int)(fractionals >> -one.e); - buffer[length] = (byte)((byte)'0' + digit); - (length)++; - fractionals &= one.f - 1; // Modulo by one. - (kappa)--; - if (fractionals < unsafe_interval.f) - { - return RoundWeed(buffer, length, DiyFp.Minus(ref too_high, ref w).f * unit, - unsafe_interval.f, fractionals, one.f, unit); - } - } - } - - // Provides a decimal representation of v. - // Returns true if it succeeds, otherwise the result cannot be trusted. - // There will be *length digits inside the buffer (not null-terminated). - // If the function returns true then - // v == (double) (buffer * 10^decimal_exponent). - // The digits in the buffer are the shortest representation possible: no - // 0.09999999999999999 instead of 0.1. The shorter representation will even be - // chosen even if the longer one would be closer to v. - // The last digit will be closest to the actual v. That is, even if several - // digits might correctly yield 'v' when read again, the closest will be - // computed. - static bool Grisu3(double v, - FastDtoaMode mode, - byte[] buffer, - out int length, - out int decimal_exponent) - { - DiyFp w = new Double(v).AsNormalizedDiyFp(); - // boundary_minus and boundary_plus are the boundaries between v and its - // closest floating-point neighbors. Any number strictly between - // boundary_minus and boundary_plus will round to v when convert to a double. - // Grisu3 will never output representations that lie exactly on a boundary. - DiyFp boundary_minus, boundary_plus; - if (mode == FastDtoaMode.FAST_DTOA_SHORTEST) - { - new Double(v).NormalizedBoundaries(out boundary_minus, out boundary_plus); - } - else if (mode == FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE) - { - float single_v = (float)(v); - new Single(single_v).NormalizedBoundaries(out boundary_minus, out boundary_plus); - } - else - { - throw new Exception("Invalid Mode."); - } - - DiyFp ten_mk; // Cached power of ten: 10^-k - int mk; // -k - int ten_mk_minimal_binary_exponent = - kMinimalTargetExponent - (w.e + DiyFp.kSignificandSize); - int ten_mk_maximal_binary_exponent = - kMaximalTargetExponent - (w.e + DiyFp.kSignificandSize); - PowersOfTenCache.GetCachedPowerForBinaryExponentRange( - ten_mk_minimal_binary_exponent, - ten_mk_maximal_binary_exponent, - out ten_mk, out mk); - - // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a - // 64 bit significand and ten_mk is thus only precise up to 64 bits. - - // The DiyFp::Times procedure rounds its result, and ten_mk is approximated - // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now - // off by a small amount. - // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. - // In other words: let f = scaled_w.f() and e = scaled_w.e(), then - // (f-1) * 2^e < w*10^k < (f+1) * 2^e - DiyFp scaled_w = DiyFp.Times(ref w, ref ten_mk); - - // In theory it would be possible to avoid some recomputations by computing - // the difference between w and boundary_minus/plus (a power of 2) and to - // compute scaled_boundary_minus/plus by subtracting/adding from - // scaled_w. However the code becomes much less readable and the speed - // enhancements are not terriffic. - DiyFp scaled_boundary_minus = DiyFp.Times(ref boundary_minus, ref ten_mk); - DiyFp scaled_boundary_plus = DiyFp.Times(ref boundary_plus, ref ten_mk); - - // DigitGen will generate the digits of scaled_w. Therefore we have - // v == (double) (scaled_w * 10^-mk). - // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an - // integer than it will be updated. For instance if scaled_w == 1.23 then - // the buffer will be filled with "123" und the decimal_exponent will be - // decreased by 2. - int kappa; - bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, - buffer, out length, out kappa); - decimal_exponent = -mk + kappa; - return result; - } - - static bool FastDtoa(double v, - FastDtoaMode mode, - // int requested_digits, - byte[] buffer, - out int length, - out int decimal_point) - { - bool result = false; - int decimal_exponent = 0; - switch (mode) - { - case FastDtoaMode.FAST_DTOA_SHORTEST: - case FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE: - result = Grisu3(v, mode, buffer, out length, out decimal_exponent); - break; - // case FastDtoaMode.FAST_DTOA_PRECISION: - //result = Grisu3Counted(v, requested_digits, buffer, length, &decimal_exponent); - default: - throw new Exception("unreachable code."); - } - if (result) - { - decimal_point = length + decimal_exponent; - } - else - { - decimal_point = -1; - } - return result; - } - - // https://github.com/google/double-conversion/blob/master/double-conversion/double-conversion.cc - - static bool HandleSpecialValues( - double value, - ref StringBuilder result_builder) - { - Double double_inspect = new Double(value); - if (double_inspect.IsInfinite()) - { - if (infinity_symbol_ == null) return false; - if (value < 0) - { - if (!result_builder.TryAddCharacter('-')) return false; - } - if (!result_builder.TryAddString(infinity_symbol_)) return false; - return true; - } - if (double_inspect.IsNan()) - { - if (nan_symbol_ == null) return false; - if (!result_builder.TryAddString(nan_symbol_)) return false; - return true; - } - return false; - } - - static bool ToShortestIeeeNumber( - double value, - ref StringBuilder result_builder, - DtoaMode mode) - { - if (new Double(value).IsSpecial()) - { - return HandleSpecialValues(value, ref result_builder); - } - - int decimal_point; - bool sign; - const int kDecimalRepCapacity = kBase10MaximalLength + 1; - var decimal_rep = GetDecimalRepBuffer(kDecimalRepCapacity); // byte[] decimal_rep = new byte[kDecimalRepCapacity]; - int decimal_rep_length; - - var fastworked = DoubleToAscii(value, mode, 0, decimal_rep, - out sign, out decimal_rep_length, out decimal_point); - - if (!fastworked) - { - // C# custom, slow path - var str = value.ToString("G17", CultureInfo.InvariantCulture); - if (!result_builder.TryAddStringSlow(str)) return false; - return true; - } - - bool unique_zero = (flags_ & Flags.UNIQUE_ZERO) != 0; - if (sign && (value != 0.0 || !unique_zero)) - { - if (!result_builder.TryAddCharacter('-')) return false; - } - - int exponent = decimal_point - 1; - if ((decimal_in_shortest_low_ <= exponent) && - (exponent < decimal_in_shortest_high_)) - { - return CreateDecimalRepresentation(decimal_rep, decimal_rep_length, - decimal_point, - Math.Max(0, decimal_rep_length - decimal_point), - ref result_builder); - } - else - { - return CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, - ref result_builder); - } - } - - static bool CreateDecimalRepresentation( - byte[] decimal_digits, - int length, - int decimal_point, - int digits_after_point, - ref StringBuilder result_builder) - { - // Create a representation that is padded with zeros if needed. - if (decimal_point <= 0) - { - // "0.00000decimal_rep" or "0.000decimal_rep00". - if (!result_builder.TryAddCharacter('0')) return false; - if (digits_after_point > 0) - { - if (!result_builder.TryAddCharacter('.')) return false; - if (!result_builder.TryAddPadding('0', -decimal_point)) return false; - if (!result_builder.TryAddSubstring(decimal_digits, length)) return false; - int remaining_digits = digits_after_point - (-decimal_point) - length; - if (!result_builder.TryAddPadding('0', remaining_digits)) return false; - } - } - else if (decimal_point >= length) - { - // "decimal_rep0000.00000" or "decimal_rep.0000". - if (!result_builder.TryAddSubstring(decimal_digits, length)) return false; - if (!result_builder.TryAddPadding('0', decimal_point - length)) return false; - if (digits_after_point > 0) - { - if (!result_builder.TryAddCharacter('.')) return false; - if (!result_builder.TryAddPadding('0', digits_after_point)) return false; - } - } - else - { - // "decima.l_rep000". - if (!result_builder.TryAddSubstring(decimal_digits, decimal_point)) return false; - if (!result_builder.TryAddCharacter('.')) return false; - if (!result_builder.TryAddSubstring(decimal_digits, decimal_point, length - decimal_point)) return false; - int remaining_digits = digits_after_point - (length - decimal_point); - if (!result_builder.TryAddPadding('0', remaining_digits)) return false; - } - if (digits_after_point == 0) - { - if ((flags_ & Flags.EMIT_TRAILING_DECIMAL_POINT) != 0) - { - if (!result_builder.TryAddCharacter('.')) return false; - } - if ((flags_ & Flags.EMIT_TRAILING_ZERO_AFTER_POINT) != 0) - { - if (!result_builder.TryAddCharacter('0')) return false; - } - } - - return true; - } - - static bool CreateExponentialRepresentation( - byte[] decimal_digits, - int length, - int exponent, - ref StringBuilder result_builder) - { - if (!result_builder.TryAddCharacter(decimal_digits[0])) return false; - if (length != 1) - { - if (!result_builder.TryAddCharacter('.')) return false; - if (!result_builder.TryAddSubstring(decimal_digits, 1, length - 1)) return false; - } - if (!result_builder.TryAddCharacter(exponent_character_)) return false; - if (exponent < 0) - { - if (!result_builder.TryAddCharacter('-')) return false; - exponent = -exponent; - } - else - { - if ((flags_ & Flags.EMIT_POSITIVE_EXPONENT_SIGN) != 0) - { - if (!result_builder.TryAddCharacter('+')) return false; - } - } - if (exponent == 0) - { - if (!result_builder.TryAddCharacter('0')) return false; - return true; - } - const int kMaxExponentLength = 5; - byte[] buffer = GetExponentialRepBuffer(kMaxExponentLength + 1); - buffer[kMaxExponentLength] = (byte)'\0'; - int first_char_pos = kMaxExponentLength; - while (exponent > 0) - { - buffer[--first_char_pos] = (byte)((byte)'0' + (exponent % 10)); - exponent /= 10; - } - if (!result_builder.TryAddSubstring(buffer, first_char_pos, kMaxExponentLength - first_char_pos)) return false; - - return true; - } - - // modified, return fast_worked. - static bool DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - //byte[] buffer, - //int buffer_length, - byte[] vector, // already allocate - out bool sign, - out int length, - out int point) - { - if (new Double(v).Sign() < 0) - { - sign = true; - v = -v; - } - else - { - sign = false; - } - - //if (mode == DtoaMode.PRECISION && requested_digits == 0) - //{ - // vector[0] = '\0'; - // *length = 0; - // return; - //} - - if (v == 0) - { - vector[0] = (byte)'0'; - // vector[1] = '\0'; - length = 1; - point = 1; - return true; - } - - bool fast_worked; - switch (mode) - { - case DtoaMode.SHORTEST: - fast_worked = FastDtoa(v, FastDtoaMode.FAST_DTOA_SHORTEST, vector, out length, out point); - break; - case DtoaMode.SHORTEST_SINGLE: - fast_worked = FastDtoa(v, FastDtoaMode.FAST_DTOA_SHORTEST_SINGLE, vector, out length, out point); - break; - //case FIXED: - // fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); - // break; - //case PRECISION: - // fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, - // vector, length, point); - // break; - default: - fast_worked = false; - throw new Exception("Unreachable code."); - } - // if (fast_worked) return; - - // If the fast dtoa didn't succeed use the slower bignum version. - // BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); - // BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); - // vector[*length] = '\0'; - - return fast_worked; - } - } -} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs deleted file mode 100644 index 55bc2fc3..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/IEEE.cs +++ /dev/null @@ -1,441 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Cysharp.Text.Internal -{ - using uint32_t = UInt32; - - [StructLayout(LayoutKind.Explicit, Pack = 1)] - internal struct UnionDoubleULong - { - [FieldOffset(0)] - public double d; - [FieldOffset(0)] - public ulong u64; - } - - [StructLayout(LayoutKind.Explicit, Pack = 1)] - internal struct UnionFloatUInt - { - [FieldOffset(0)] - public float f; - [FieldOffset(0)] - public uint u32; - } - - // https://github.com/google/double-conversion/blob/master/double-conversion/ieee.h - - internal struct Double - { - public const ulong kSignMask = (0x8000000000000000); - public const ulong kExponentMask = (0x7FF0000000000000); - public const ulong kSignificandMask = (0x000FFFFFFFFFFFFF); - public const ulong kHiddenBit = (0x0010000000000000); - public const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. - public const int kSignificandSize = 53; - - const int kExponentBias = 0x3FF + kPhysicalSignificandSize; - const int kDenormalExponent = -kExponentBias + 1; - const int kMaxExponent = 0x7FF - kExponentBias; - const ulong kInfinity = (0x7FF0000000000000); - const ulong kNaN = (0x7FF8000000000000); - - ulong d64_; - - public Double(double d) - { - d64_ = new UnionDoubleULong { d = d }.u64; - } - - public Double(DiyFp d) - { - d64_ = DiyFpToUint64(d); - } - - // The value encoded by this Double must be greater or equal to +0.0. - // It must not be special (infinity, or NaN). - public DiyFp AsDiyFp() - { - return new DiyFp(Significand(), Exponent()); - } - - // The value encoded by this Double must be strictly greater than 0. - public DiyFp AsNormalizedDiyFp() - { - ulong f = Significand(); - int e = Exponent(); - - // The current double could be a denormal. - while ((f & kHiddenBit) == 0) - { - f <<= 1; - e--; - } - // Do the final shifts in one go. - f <<= DiyFp.kSignificandSize - kSignificandSize; - e -= DiyFp.kSignificandSize - kSignificandSize; - return new DiyFp(f, e); - } - - // Returns the double's bit as uint64. - public ulong AsUint64() - { - return d64_; - } - - // Returns the next greater double. Returns +infinity on input +infinity. - public double NextDouble() - { - if (d64_ == kInfinity) return new Double(kInfinity).value(); - if (Sign() < 0 && Significand() == 0) - { - // -0.0 - return 0.0; - } - if (Sign() < 0) - { - return new Double(d64_ - 1).value(); - } - else - { - return new Double(d64_ + 1).value(); - } - } - - public double PreviousDouble() - { - if (d64_ == (kInfinity | kSignMask)) return -Infinity(); - if (Sign() < 0) - { - return new Double(d64_ + 1).value(); - } - else - { - if (Significand() == 0) return -0.0; - return new Double(d64_ - 1).value(); - } - } - - public int Exponent() - { - if (IsDenormal()) return kDenormalExponent; - - ulong d64 = AsUint64(); - int biased_e = - (int)((d64 & kExponentMask) >> kPhysicalSignificandSize); - return biased_e - kExponentBias; - } - - public ulong Significand() - { - ulong d64 = AsUint64(); - ulong significand = d64 & kSignificandMask; - if (!IsDenormal()) - { - return significand + kHiddenBit; - } - else - { - return significand; - } - } - - // Returns true if the double is a denormal. - public bool IsDenormal() - { - ulong d64 = AsUint64(); - return (d64 & kExponentMask) == 0; - } - - // We consider denormals not to be special. - // Hence only Infinity and NaN are special. - public bool IsSpecial() - { - ulong d64 = AsUint64(); - return (d64 & kExponentMask) == kExponentMask; - } - - public bool IsNan() - { - ulong d64 = AsUint64(); - return ((d64 & kExponentMask) == kExponentMask) && - ((d64 & kSignificandMask) != 0); - } - - public bool IsInfinite() - { - ulong d64 = AsUint64(); - return ((d64 & kExponentMask) == kExponentMask) && - ((d64 & kSignificandMask) == 0); - } - - public int Sign() - { - ulong d64 = AsUint64(); - return (d64 & kSignMask) == 0 ? 1 : -1; - } - - // Precondition: the value encoded by this Double must be greater or equal - // than +0.0. - public DiyFp UpperBoundary() - { - return new DiyFp(Significand() * 2 + 1, Exponent() - 1); - } - - // Computes the two boundaries of this. - // The bigger boundary (m_plus) is normalized. The lower boundary has the same - // exponent as m_plus. - // Precondition: the value encoded by this Double must be greater than 0. - public void NormalizedBoundaries(out DiyFp out_m_minus, out DiyFp out_m_plus) - { - DiyFp v = this.AsDiyFp(); - var __ = new DiyFp((v.f << 1) + 1, v.e - 1); - var m_plus = DiyFp.Normalize(ref __); - - DiyFp m_minus; - if (LowerBoundaryIsCloser()) - { - m_minus = new DiyFp((v.f << 2) - 1, v.e - 2); - } - else - { - m_minus = new DiyFp((v.f << 1) - 1, v.e - 1); - } - m_minus.f = m_minus.f << (m_minus.e - m_plus.e); - m_minus.e = (m_plus.e); - out_m_plus = m_plus; - out_m_minus = m_minus; - } - - public bool LowerBoundaryIsCloser() - { - // The boundary is closer if the significand is of the form f == 2^p-1 then - // the lower boundary is closer. - // Think of v = 1000e10 and v- = 9999e9. - // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but - // at a distance of 1e8. - // The only exception is for the smallest normal: the largest denormal is - // at the same distance as its successor. - // Note: denormals have the same exponent as the smallest normals. - bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0); - return physical_significand_is_zero && (Exponent() != kDenormalExponent); - } - - public double value() - { - return new UnionDoubleULong { u64 = d64_ }.d; - } - - // Returns the significand size for a given order of magnitude. - // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude. - // This function returns the number of significant binary digits v will have - // once it's encoded into a double. In almost all cases this is equal to - // kSignificandSize. The only exceptions are denormals. They start with - // leading zeroes and their effective significand-size is hence smaller. - public static int SignificandSizeForOrderOfMagnitude(int order) - { - if (order >= (kDenormalExponent + kSignificandSize)) - { - return kSignificandSize; - } - if (order <= kDenormalExponent) return 0; - return order - kDenormalExponent; - } - - public static double Infinity() - { - return new Double(kInfinity).value(); - } - - public static double NaN() - { - return new Double(kNaN).value(); - } - - public static ulong DiyFpToUint64(DiyFp diy_fp) - { - ulong significand = diy_fp.f; - int exponent = diy_fp.e; - while (significand > kHiddenBit + kSignificandMask) - { - significand >>= 1; - exponent++; - } - if (exponent >= kMaxExponent) - { - return kInfinity; - } - if (exponent < kDenormalExponent) - { - return 0; - } - while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) - { - significand <<= 1; - exponent--; - } - ulong biased_exponent; - if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) - { - biased_exponent = 0; - } - else - { - biased_exponent = (ulong)(exponent + kExponentBias); - } - return (significand & kSignificandMask) | - (biased_exponent << kPhysicalSignificandSize); - } - } - - internal struct Single - { - const int kExponentBias = 0x7F + kPhysicalSignificandSize; - const int kDenormalExponent = -kExponentBias + 1; - const int kMaxExponent = 0xFF - kExponentBias; - const uint32_t kInfinity = 0x7F800000; - const uint32_t kNaN = 0x7FC00000; - - public const uint32_t kSignMask = 0x80000000; - public const uint32_t kExponentMask = 0x7F800000; - public const uint32_t kSignificandMask = 0x007FFFFF; - public const uint32_t kHiddenBit = 0x00800000; - public const int kPhysicalSignificandSize = 23; // Excludes the hidden bit. - public const int kSignificandSize = 24; - - uint32_t d32_; - - public Single(float f) - { - this.d32_ = new UnionFloatUInt { f = f }.u32; - } - - // The value encoded by this Single must be greater or equal to +0.0. - // It must not be special (infinity, or NaN). - public DiyFp AsDiyFp() - { - return new DiyFp(Significand(), Exponent()); - } - - // Returns the single's bit as uint64. - public uint32_t AsUint32() - { - return d32_; - } - - public int Exponent() - { - if (IsDenormal()) return kDenormalExponent; - - uint32_t d32 = AsUint32(); - int biased_e = (int)((d32 & kExponentMask) >> kPhysicalSignificandSize); - return biased_e - kExponentBias; - } - - public uint32_t Significand() - { - uint32_t d32 = AsUint32(); - uint32_t significand = d32 & kSignificandMask; - if (!IsDenormal()) - { - return significand + kHiddenBit; - } - else - { - return significand; - } - } - - // Returns true if the single is a denormal. - public bool IsDenormal() - { - uint32_t d32 = AsUint32(); - return (d32 & kExponentMask) == 0; - } - - // We consider denormals not to be special. - // Hence only Infinity and NaN are special. - public bool IsSpecial() - { - uint32_t d32 = AsUint32(); - return (d32 & kExponentMask) == kExponentMask; - } - - public bool IsNan() - { - uint32_t d32 = AsUint32(); - return ((d32 & kExponentMask) == kExponentMask) && - ((d32 & kSignificandMask) != 0); - } - - public bool IsInfinite() - { - uint32_t d32 = AsUint32(); - return ((d32 & kExponentMask) == kExponentMask) && - ((d32 & kSignificandMask) == 0); - } - - public int Sign() - { - uint32_t d32 = AsUint32(); - return (d32 & kSignMask) == 0 ? 1 : -1; - } - - // Computes the two boundaries of this. - // The bigger boundary (m_plus) is normalized. The lower boundary has the same - // exponent as m_plus. - // Precondition: the value encoded by this Single must be greater than 0. - public void NormalizedBoundaries(out DiyFp out_m_minus, out DiyFp out_m_plus) - { - DiyFp v = this.AsDiyFp(); - var __ = new DiyFp((v.f << 1) + 1, v.e - 1); - DiyFp m_plus = DiyFp.Normalize(ref __); - DiyFp m_minus; - if (LowerBoundaryIsCloser()) - { - m_minus = new DiyFp((v.f << 2) - 1, v.e - 2); - } - else - { - m_minus = new DiyFp((v.f << 1) - 1, v.e - 1); - } - m_minus.f = (m_minus.f << (m_minus.e - m_plus.e)); - m_minus.e = (m_plus.e); - out_m_plus = m_plus; - out_m_minus = m_minus; - } - - // Precondition: the value encoded by this Single must be greater or equal - // than +0.0. - public DiyFp UpperBoundary() - { - return new DiyFp(Significand() * 2 + 1, Exponent() - 1); - } - - public bool LowerBoundaryIsCloser() - { - // The boundary is closer if the significand is of the form f == 2^p-1 then - // the lower boundary is closer. - // Think of v = 1000e10 and v- = 9999e9. - // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but - // at a distance of 1e8. - // The only exception is for the smallest normal: the largest denormal is - // at the same distance as its successor. - // Note: denormals have the same exponent as the smallest normals. - bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0); - return physical_significand_is_zero && (Exponent() != kDenormalExponent); - } - - public float value() { return new UnionFloatUInt { u32 = d32_ }.f; } - - public static float Infinity() - { - return new Single(kInfinity).value(); - } - - public static float NaN() - { - return new Single(kNaN).value(); - } - } -} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs deleted file mode 100644 index 2150d858..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/PowersOfTenCache.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text.Internal -{ - using uint64_t = UInt64; - using int16_t = Int16; - - // https://github.com/google/double-conversion/blob/master/double-conversion/cached-powers.h - // https://github.com/google/double-conversion/blob/master/double-conversion/cached-powers.cc - - internal struct CachedPower - { - public readonly uint64_t significand; - public readonly int16_t binary_exponent; - public readonly int16_t decimal_exponent; - - public CachedPower(ulong significand, short binary_exponent, short decimal_exponent) - { - this.significand = significand; - this.binary_exponent = binary_exponent; - this.decimal_exponent = decimal_exponent; - } - }; - - internal static class PowersOfTenCache - { - static readonly CachedPower[] kCachedPowers = new CachedPower[] - { - new CachedPower (0xfa8fd5a0081c0288, -1220, -348), - new CachedPower (0xbaaee17fa23ebf76, -1193, -340), - new CachedPower (0x8b16fb203055ac76, -1166, -332), - new CachedPower (0xcf42894a5dce35ea, -1140, -324), - new CachedPower (0x9a6bb0aa55653b2d, -1113, -316), - new CachedPower (0xe61acf033d1a45df, -1087, -308), - new CachedPower (0xab70fe17c79ac6ca, -1060, -300), - new CachedPower (0xff77b1fcbebcdc4f, -1034, -292), - new CachedPower (0xbe5691ef416bd60c, -1007, -284), - new CachedPower (0x8dd01fad907ffc3c, -980, -276), - new CachedPower (0xd3515c2831559a83, -954, -268), - new CachedPower (0x9d71ac8fada6c9b5, -927, -260), - new CachedPower (0xea9c227723ee8bcb, -901, -252), - new CachedPower (0xaecc49914078536d, -874, -244), - new CachedPower (0x823c12795db6ce57, -847, -236), - new CachedPower (0xc21094364dfb5637, -821, -228), - new CachedPower (0x9096ea6f3848984f, -794, -220), - new CachedPower (0xd77485cb25823ac7, -768, -212), - new CachedPower (0xa086cfcd97bf97f4, -741, -204), - new CachedPower (0xef340a98172aace5, -715, -196), - new CachedPower (0xb23867fb2a35b28e, -688, -188), - new CachedPower (0x84c8d4dfd2c63f3b, -661, -180), - new CachedPower (0xc5dd44271ad3cdba, -635, -172), - new CachedPower (0x936b9fcebb25c996, -608, -164), - new CachedPower (0xdbac6c247d62a584, -582, -156), - new CachedPower (0xa3ab66580d5fdaf6, -555, -148), - new CachedPower (0xf3e2f893dec3f126, -529, -140), - new CachedPower (0xb5b5ada8aaff80b8, -502, -132), - new CachedPower (0x87625f056c7c4a8b, -475, -124), - new CachedPower (0xc9bcff6034c13053, -449, -116), - new CachedPower (0x964e858c91ba2655, -422, -108), - new CachedPower (0xdff9772470297ebd, -396, -100), - new CachedPower (0xa6dfbd9fb8e5b88f, -369, -92), - new CachedPower (0xf8a95fcf88747d94, -343, -84), - new CachedPower (0xb94470938fa89bcf, -316, -76), - new CachedPower (0x8a08f0f8bf0f156b, -289, -68), - new CachedPower (0xcdb02555653131b6, -263, -60), - new CachedPower (0x993fe2c6d07b7fac, -236, -52), - new CachedPower (0xe45c10c42a2b3b06, -210, -44), - new CachedPower (0xaa242499697392d3, -183, -36), - new CachedPower (0xfd87b5f28300ca0e, -157, -28), - new CachedPower (0xbce5086492111aeb, -130, -20), - new CachedPower (0x8cbccc096f5088cc, -103, -12), - new CachedPower (0xd1b71758e219652c, -77, -4), - new CachedPower (0x9c40000000000000, -50, 4), - new CachedPower (0xe8d4a51000000000, -24, 12), - new CachedPower (0xad78ebc5ac620000, 3, 20), - new CachedPower (0x813f3978f8940984, 30, 28), - new CachedPower (0xc097ce7bc90715b3, 56, 36), - new CachedPower (0x8f7e32ce7bea5c70, 83, 44), - new CachedPower (0xd5d238a4abe98068, 109, 52), - new CachedPower (0x9f4f2726179a2245, 136, 60), - new CachedPower (0xed63a231d4c4fb27, 162, 68), - new CachedPower (0xb0de65388cc8ada8, 189, 76), - new CachedPower (0x83c7088e1aab65db, 216, 84), - new CachedPower (0xc45d1df942711d9a, 242, 92), - new CachedPower (0x924d692ca61be758, 269, 100), - new CachedPower (0xda01ee641a708dea, 295, 108), - new CachedPower (0xa26da3999aef774a, 322, 116), - new CachedPower (0xf209787bb47d6b85, 348, 124), - new CachedPower (0xb454e4a179dd1877, 375, 132), - new CachedPower (0x865b86925b9bc5c2, 402, 140), - new CachedPower (0xc83553c5c8965d3d, 428, 148), - new CachedPower (0x952ab45cfa97a0b3, 455, 156), - new CachedPower (0xde469fbd99a05fe3, 481, 164), - new CachedPower (0xa59bc234db398c25, 508, 172), - new CachedPower (0xf6c69a72a3989f5c, 534, 180), - new CachedPower (0xb7dcbf5354e9bece, 561, 188), - new CachedPower (0x88fcf317f22241e2, 588, 196), - new CachedPower (0xcc20ce9bd35c78a5, 614, 204), - new CachedPower (0x98165af37b2153df, 641, 212), - new CachedPower (0xe2a0b5dc971f303a, 667, 220), - new CachedPower (0xa8d9d1535ce3b396, 694, 228), - new CachedPower (0xfb9b7cd9a4a7443c, 720, 236), - new CachedPower (0xbb764c4ca7a44410, 747, 244), - new CachedPower (0x8bab8eefb6409c1a, 774, 252), - new CachedPower (0xd01fef10a657842c, 800, 260), - new CachedPower (0x9b10a4e5e9913129, 827, 268), - new CachedPower (0xe7109bfba19c0c9d, 853, 276), - new CachedPower (0xac2820d9623bf429, 880, 284), - new CachedPower (0x80444b5e7aa7cf85, 907, 292), - new CachedPower (0xbf21e44003acdd2d, 933, 300), - new CachedPower (0x8e679c2f5e44ff8f, 960, 308), - new CachedPower (0xd433179d9c8cb841, 986, 316), - new CachedPower (0x9e19db92b4e31ba9, 1013, 324), - new CachedPower (0xeb96bf6ebadf77d9, 1039, 332), - new CachedPower (0xaf87023b9bf0ee6b, 1066, 340), - }; - - public const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent. - public const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) - // Difference between the decimal exponents in the table above. - public const int kDecimalExponentDistance = 8; - public const int kMinDecimalExponent = -348; - public const int kMaxDecimalExponent = 340; - - public static void GetCachedPowerForBinaryExponentRange( - int min_exponent, - int max_exponent, - out DiyFp power, - out int decimal_exponent) - { - int kQ = DiyFp.kSignificandSize; - double k = Math.Ceiling((min_exponent + kQ - 1) * kD_1_LOG2_10); - int foo = kCachedPowersOffset; - int index = (foo + (int)(k) - 1) / kDecimalExponentDistance + 1; - - CachedPower cached_power = kCachedPowers[index]; - // (void)max_exponent; // Mark variable as used. - decimal_exponent = cached_power.decimal_exponent; - power = new DiyFp(cached_power.significand, cached_power.binary_exponent); - } - - public static void GetCachedPowerForDecimalExponent(int requested_exponent, - out DiyFp power, - out int found_exponent) - { - int index = (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance; - CachedPower cached_power = kCachedPowers[index]; - power = new DiyFp(cached_power.significand, cached_power.binary_exponent); - found_exponent = cached_power.decimal_exponent; - } - } -} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs deleted file mode 100644 index 0c65eb55..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs +++ /dev/null @@ -1,535 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text.Internal -{ - using uint64_t = UInt64; - - internal struct Vector - { - public readonly byte[] bytes; - public readonly int start; - public readonly int _length; - - public Vector(byte[] bytes, int start, int length) - { - this.bytes = bytes; - this.start = start; - this._length = length; - } - - public byte this[int i] - { - get - { - return bytes[start + i]; - } - set - { - bytes[start + i] = value; - } - } - - public int length() - { - return _length; - } - - public byte first() - { - return bytes[start]; - } - - public byte last() - { - return bytes[_length - 1]; - } - - public bool is_empty() - { - return _length == 0; - } - - public Vector SubVector(int from, int to) - { - return new Vector(this.bytes, start + from, to - from); - } - } - - internal static class StringToDouble - { - [ThreadStatic] - static byte[] copyBuffer; - - static byte[] GetCopyBuffer() - { - if (copyBuffer == null) - { - copyBuffer = new byte[kMaxSignificantDecimalDigits]; - } - return copyBuffer; - } - - // 2^53 = 9007199254740992. - // Any integer with at most 15 decimal digits will hence fit into a double - // (which has a 53bit significand) without loss of precision. - const int kMaxExactDoubleIntegerDecimalDigits = 15; - // 2^64 = 18446744073709551616 > 10^19 - const int kMaxUint64DecimalDigits = 19; - - // Max double: 1.7976931348623157 x 10^308 - // Min non-zero double: 4.9406564584124654 x 10^-324 - // Any x >= 10^309 is interpreted as +infinity. - // Any x <= 10^-324 is interpreted as 0. - // Note that 2.5e-324 (despite being smaller than the min double) will be read - // as non-zero (equal to the min non-zero double). - const int kMaxDecimalPower = 309; - const int kMinDecimalPower = -324; - - // 2^64 = 18446744073709551616 - const uint64_t kMaxUint64 = 0xFFFFFFFFFFFFFFFF; - - static readonly double[] exact_powers_of_ten = new double[]{ - 1.0, // 10^0 - 10.0, - 100.0, - 1000.0, - 10000.0, - 100000.0, - 1000000.0, - 10000000.0, - 100000000.0, - 1000000000.0, - 10000000000.0, // 10^10 - 100000000000.0, - 1000000000000.0, - 10000000000000.0, - 100000000000000.0, - 1000000000000000.0, - 10000000000000000.0, - 100000000000000000.0, - 1000000000000000000.0, - 10000000000000000000.0, - 100000000000000000000.0, // 10^20 - 1000000000000000000000.0, - // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22 - 10000000000000000000000.0 - }; - static readonly int kExactPowersOfTenSize = exact_powers_of_ten.Length; - - // Maximum number of significant digits in the decimal representation. - // In fact the value is 772 (see conversions.cc), but to give us some margin - // we round up to 780. - const int kMaxSignificantDecimalDigits = 780; - - static Vector TrimLeadingZeros(Vector buffer) - { - for (int i = 0; i < buffer.length(); i++) - { - if (buffer[i] != '0') - { - return buffer.SubVector(i, buffer.length()); - } - } - return new Vector(buffer.bytes, buffer.start, 0); - } - - static Vector TrimTrailingZeros(Vector buffer) - { - for (int i = buffer.length() - 1; i >= 0; --i) - { - if (buffer[i] != '0') - { - return buffer.SubVector(0, i + 1); - } - } - return new Vector(buffer.bytes, buffer.start, 0); - } - - - static void CutToMaxSignificantDigits(Vector buffer, - int exponent, - byte[] significant_buffer, - out int significant_exponent) - { - for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) - { - significant_buffer[i] = buffer[i]; - } - // The input buffer has been trimmed. Therefore the last digit must be - // different from '0'. - // ASSERT(buffer[buffer.length() - 1] != '0'); - // Set the last digit to be non-zero. This is sufficient to guarantee - // correct rounding. - significant_buffer[kMaxSignificantDecimalDigits - 1] = (byte)'1'; - significant_exponent = exponent + (buffer.length() - kMaxSignificantDecimalDigits); - } - - // Trims the buffer and cuts it to at most kMaxSignificantDecimalDigits. - // If possible the input-buffer is reused, but if the buffer needs to be - // modified (due to cutting), then the input needs to be copied into the - // buffer_copy_space. - static void TrimAndCut(Vector buffer, int exponent, - byte[] buffer_copy_space, int space_size, - out Vector trimmed, out int updated_exponent) - { - Vector left_trimmed = TrimLeadingZeros(buffer); - Vector right_trimmed = TrimTrailingZeros(left_trimmed); - exponent += left_trimmed.length() - right_trimmed.length(); - if (right_trimmed.length() > kMaxSignificantDecimalDigits) - { - // (void)space_size; // Mark variable as used. - CutToMaxSignificantDigits(right_trimmed, exponent, - buffer_copy_space, out updated_exponent); - trimmed = new Vector(buffer_copy_space, 0, kMaxSignificantDecimalDigits); - } - else - { - trimmed = right_trimmed; - updated_exponent = exponent; - } - } - - - // Reads digits from the buffer and converts them to a uint64. - // Reads in as many digits as fit into a uint64. - // When the string starts with "1844674407370955161" no further digit is read. - // Since 2^64 = 18446744073709551616 it would still be possible read another - // digit if it was less or equal than 6, but this would complicate the code. - static uint64_t ReadUint64(Vector buffer, - out int number_of_read_digits) - { - uint64_t result = 0; - int i = 0; - while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) - { - int digit = buffer[i++] - '0'; - result = 10 * result + (ulong)digit; - } - number_of_read_digits = i; - return result; - } - - // Reads a DiyFp from the buffer. - // The returned DiyFp is not necessarily normalized. - // If remaining_decimals is zero then the returned DiyFp is accurate. - // Otherwise it has been rounded and has error of at most 1/2 ulp. - static void ReadDiyFp(Vector buffer, - out DiyFp result, - out int remaining_decimals) - { - int read_digits; - uint64_t significand = ReadUint64(buffer, out read_digits); - if (buffer.length() == read_digits) - { - result = new DiyFp(significand, 0); - remaining_decimals = 0; - } - else - { - // Round the significand. - if (buffer[read_digits] >= '5') - { - significand++; - } - // Compute the binary exponent. - int exponent = 0; - result = new DiyFp(significand, exponent); - remaining_decimals = buffer.length() - read_digits; - } - } - - - static bool DoubleStrtod(Vector trimmed, - int exponent, - out double result) - { - if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) - { - int read_digits; - // The trimmed input fits into a double. - // If the 10^exponent (resp. 10^-exponent) fits into a double too then we - // can compute the result-double simply by multiplying (resp. dividing) the - // two numbers. - // This is possible because IEEE guarantees that floating-point operations - // return the best possible approximation. - if (exponent < 0 && -exponent < kExactPowersOfTenSize) - { - // 10^-exponent fits into a double. - result = unchecked((double)(ReadUint64(trimmed, out read_digits))); - result /= exact_powers_of_ten[-exponent]; - return true; - } - if (0 <= exponent && exponent < kExactPowersOfTenSize) - { - // 10^exponent fits into a double. - result = unchecked((double)(ReadUint64(trimmed, out read_digits))); - result *= exact_powers_of_ten[exponent]; - return true; - } - int remaining_digits = - kMaxExactDoubleIntegerDecimalDigits - trimmed.length(); - if ((0 <= exponent) && - (exponent - remaining_digits < kExactPowersOfTenSize)) - { - // The trimmed string was short and we can multiply it with - // 10^remaining_digits. As a result the remaining exponent now fits - // into a double too. - result = unchecked((double)(ReadUint64(trimmed, out read_digits))); - result *= exact_powers_of_ten[remaining_digits]; - result *= exact_powers_of_ten[exponent - remaining_digits]; - return true; - } - } - result = 0; - return false; - } - - - // Returns 10^exponent as an exact DiyFp. - // The given exponent must be in the range [1; kDecimalExponentDistance[. - static DiyFp AdjustmentPowerOfTen(int exponent) - { - // Simply hardcode the remaining powers for the given decimal exponent - // distance. - switch (exponent) - { - case 1: return new DiyFp(0xa000000000000000, -60); - case 2: return new DiyFp(0xc800000000000000, -57); - case 3: return new DiyFp(0xfa00000000000000, -54); - case 4: return new DiyFp(0x9c40000000000000, -50); - case 5: return new DiyFp(0xc350000000000000, -47); - case 6: return new DiyFp(0xf424000000000000, -44); - case 7: return new DiyFp(0x9896800000000000, -40); - default: - throw new Exception("unreached code."); - } - } - - // If the function returns true then the result is the correct double. - // Otherwise it is either the correct double or the double that is just below - // the correct double. - static bool DiyFpStrtod(Vector buffer, - int exponent, - out double result) - { - DiyFp input; - int remaining_decimals; - ReadDiyFp(buffer, out input, out remaining_decimals); - // Since we may have dropped some digits the input is not accurate. - // If remaining_decimals is different than 0 than the error is at most - // .5 ulp (unit in the last place). - // We don't want to deal with fractions and therefore keep a common - // denominator. - const int kDenominatorLog = 3; - const int kDenominator = 1 << kDenominatorLog; - // Move the remaining decimals into the exponent. - exponent += remaining_decimals; - uint64_t error = (ulong)(remaining_decimals == 0 ? 0 : kDenominator / 2); - - int old_e = input.e; - input.Normalize(); - error <<= old_e - input.e; - - if (exponent < PowersOfTenCache.kMinDecimalExponent) - { - result = 0.0; - return true; - } - DiyFp cached_power; - int cached_decimal_exponent; - PowersOfTenCache.GetCachedPowerForDecimalExponent(exponent, - out cached_power, - out cached_decimal_exponent); - - if (cached_decimal_exponent != exponent) - { - int adjustment_exponent = exponent - cached_decimal_exponent; - DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent); - input.Multiply(ref adjustment_power); - if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) - { - // The product of input with the adjustment power fits into a 64 bit - // integer. - } - else - { - // The adjustment power is exact. There is hence only an error of 0.5. - error += kDenominator / 2; - } - } - - input.Multiply(ref cached_power); - // The error introduced by a multiplication of a*b equals - // error_a + error_b + error_a*error_b/2^64 + 0.5 - // Substituting a with 'input' and b with 'cached_power' we have - // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp), - // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64 - int error_b = kDenominator / 2; - int error_ab = (error == 0 ? 0 : 1); // We round up to 1. - int fixed_error = kDenominator / 2; - error += (ulong)(error_b + error_ab + fixed_error); - - old_e = input.e; - input.Normalize(); - error <<= old_e - input.e; - - // See if the double's significand changes if we add/subtract the error. - int order_of_magnitude = DiyFp.kSignificandSize + input.e; - int effective_significand_size = Double.SignificandSizeForOrderOfMagnitude(order_of_magnitude); - int precision_digits_count = DiyFp.kSignificandSize - effective_significand_size; - if (precision_digits_count + kDenominatorLog >= DiyFp.kSignificandSize) - { - // This can only happen for very small denormals. In this case the - // half-way multiplied by the denominator exceeds the range of an uint64. - // Simply shift everything to the right. - int shift_amount = (precision_digits_count + kDenominatorLog) - - DiyFp.kSignificandSize + 1; - input.f = (input.f >> shift_amount); - input.e = (input.e + shift_amount); - // We add 1 for the lost precision of error, and kDenominator for - // the lost precision of input.f(). - error = (error >> shift_amount) + 1 + kDenominator; - precision_digits_count -= shift_amount; - } - // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too. - uint64_t one64 = 1; - uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1; - uint64_t precision_bits = input.f & precision_bits_mask; - uint64_t half_way = one64 << (precision_digits_count - 1); - precision_bits *= kDenominator; - half_way *= kDenominator; - DiyFp rounded_input = new DiyFp(input.f >> precision_digits_count, input.e + precision_digits_count); - if (precision_bits >= half_way + error) - { - rounded_input.f = (rounded_input.f + 1); - } - // If the last_bits are too close to the half-way case than we are too - // inaccurate and round down. In this case we return false so that we can - // fall back to a more precise algorithm. - - result = new Double(rounded_input).value(); - if (half_way - error < precision_bits && precision_bits < half_way + error) - { - // Too imprecise. The caller will have to fall back to a slower version. - // However the returned number is guaranteed to be either the correct - // double, or the next-lower double. - return false; - } - else - { - return true; - } - } - - // Returns true if the guess is the correct double. - // Returns false, when guess is either correct or the next-lower double. - static bool ComputeGuess(Vector trimmed, int exponent, - out double guess) - { - if (trimmed.length() == 0) - { - guess = 0.0; - return true; - } - if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) - { - guess = Double.Infinity(); - return true; - } - if (exponent + trimmed.length() <= kMinDecimalPower) - { - guess = 0.0; - return true; - } - - if (DoubleStrtod(trimmed, exponent, out guess) || - DiyFpStrtod(trimmed, exponent, out guess)) - { - return true; - } - if (guess == Double.Infinity()) - { - return true; - } - return false; - } - - public static double? Strtod(Vector buffer, int exponent) - { - byte[] copy_buffer = GetCopyBuffer(); - Vector trimmed; - int updated_exponent; - TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, - out trimmed, out updated_exponent); - exponent = updated_exponent; - - double guess; - var is_correct = ComputeGuess(trimmed, exponent, out guess); - if (is_correct) return guess; - return null; - } - - public static float? Strtof(Vector buffer, int exponent) - { - byte[] copy_buffer = GetCopyBuffer(); - Vector trimmed; - int updated_exponent; - TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, - out trimmed, out updated_exponent); - exponent = updated_exponent; - - double double_guess; - var is_correct = ComputeGuess(trimmed, exponent, out double_guess); - - float float_guess = (float)(double_guess); - if (float_guess == double_guess) - { - // This shortcut triggers for integer values. - return float_guess; - } - - // We must catch double-rounding. Say the double has been rounded up, and is - // now a boundary of a float, and rounds up again. This is why we have to - // look at previous too. - // Example (in decimal numbers): - // input: 12349 - // high-precision (4 digits): 1235 - // low-precision (3 digits): - // when read from input: 123 - // when rounded from high precision: 124. - // To do this we simply look at the neigbors of the correct result and see - // if they would round to the same float. If the guess is not correct we have - // to look at four values (since two different doubles could be the correct - // double). - - double double_next = new Double(double_guess).NextDouble(); - double double_previous = new Double(double_guess).PreviousDouble(); - - float f1 = (float)(double_previous); - // float f2 = float_guess; - float f3 = (float)(double_next); - float f4; - if (is_correct) - { - f4 = f3; - } - else - { - double double_next2 = new Double(double_next).NextDouble(); - f4 = (float)(double_next2); - } - // (void)f2; // Mark variable as used. - - // If the guess doesn't lie near a single-precision boundary we can simply - // return its float-value. - if (f1 == f4) - { - return float_guess; - } - - return null; - } - } -} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs.meta deleted file mode 100644 index 551d4e0a..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDouble.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 12065a632080740419231e5d927b6b2e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs deleted file mode 100644 index 67cbe2a1..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs +++ /dev/null @@ -1,625 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Cysharp.Text.Internal -{ -#pragma warning disable 660 -#pragma warning disable 661 - - internal struct Iterator - { - byte[] buffer; - int offset; - - public Iterator(byte[] buffer, int offset) - { - this.buffer = buffer; - this.offset = offset; - } - - public byte Value - { - get - { - return buffer[offset]; - } - } - - public static Iterator operator ++(Iterator self) - { - self.offset++; - return self; - } - - public static Iterator operator +(Iterator self, int length) - { - return new Iterator { buffer = self.buffer, offset = self.offset + length }; - } - - public static int operator -(Iterator lhs, Iterator rhs) - { - return lhs.offset - rhs.offset; - } - - public static bool operator ==(Iterator lhs, Iterator rhs) - { - return lhs.offset == rhs.offset; - } - - public static bool operator !=(Iterator lhs, Iterator rhs) - { - return lhs.offset != rhs.offset; - } - - public static bool operator ==(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] == (byte)rhs; - } - - public static bool operator !=(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] != (byte)rhs; - } - - public static bool operator ==(Iterator lhs, byte rhs) - { - return lhs.buffer[lhs.offset] == (byte)rhs; - } - - public static bool operator !=(Iterator lhs, byte rhs) - { - return lhs.buffer[lhs.offset] != (byte)rhs; - } - - public static bool operator >=(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] >= (byte)rhs; - } - - public static bool operator <=(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] <= (byte)rhs; - } - - public static bool operator >(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] > (byte)rhs; - } - - public static bool operator <(Iterator lhs, char rhs) - { - return lhs.buffer[lhs.offset] < (byte)rhs; - } - } - -#pragma warning restore 661 -#pragma warning restore 660 - - // C# API - internal static partial class StringToDoubleConverter - { - [ThreadStatic] - static byte[] kBuffer; - - static byte[] GetBuffer() - { - if (kBuffer == null) - { - kBuffer = new byte[kBufferSize]; - } - return kBuffer; - } - - [ThreadStatic] - static byte[] fallbackBuffer; - - static byte[] GetFallbackBuffer() - { - if (fallbackBuffer == null) - { - fallbackBuffer = new byte[99]; - } - return fallbackBuffer; - } - - public static double ToDouble(byte[] buffer, int offset, out int readCount) - { - return StringToIeee(new Iterator(buffer, offset), buffer.Length - offset, true, out readCount); - } - - public static float ToSingle(byte[] buffer, int offset, out int readCount) - { - return unchecked((float)StringToIeee(new Iterator(buffer, offset), buffer.Length - offset, false, out readCount)); - } - } - - // port - internal static partial class StringToDoubleConverter - { - enum Flags - { - NO_FLAGS = 0, - ALLOW_HEX = 1, // defined but always disallow - ALLOW_OCTALS = 2, - ALLOW_TRAILING_JUNK = 4, - ALLOW_LEADING_SPACES = 8, - ALLOW_TRAILING_SPACES = 16, - ALLOW_SPACES_AFTER_SIGN = 32, - ALLOW_CASE_INSENSIBILITY = 64, // not supported - }; - - const Flags flags_ = Flags.ALLOW_TRAILING_JUNK | Flags.ALLOW_TRAILING_SPACES | Flags.ALLOW_SPACES_AFTER_SIGN; - const double empty_string_value_ = 0.0; - const double junk_string_value_ = double.NaN; - const int kMaxSignificantDigits = 772; - const int kBufferSize = kMaxSignificantDigits + 10; - static readonly byte[] infinity_symbol_ = Encoding.UTF8.GetBytes(double.PositiveInfinity.ToString()); - static readonly byte[] nan_symbol_ = Encoding.UTF8.GetBytes(double.NaN.ToString()); - - static readonly byte[] kWhitespaceTable7 = new byte[] { 32, 13, 10, 9, 11, 12 }; - static readonly int kWhitespaceTable7Length = kWhitespaceTable7.Length; - - static readonly UInt16[] kWhitespaceTable16 = new UInt16[]{ - 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195, - 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279 - }; - static readonly int kWhitespaceTable16Length = kWhitespaceTable16.Length; - - static bool isWhitespace(int x) - { - if (x < 128) - { - for (int i = 0; i < kWhitespaceTable7Length; i++) - { - if (kWhitespaceTable7[i] == x) return true; - } - } - else - { - for (int i = 0; i < kWhitespaceTable16Length; i++) - { - if (kWhitespaceTable16[i] == x) return true; - } - } - return false; - } - - static bool AdvanceToNonspace(ref Iterator current, Iterator end) - { - while (current != end) - { - if (!isWhitespace(current.Value)) return true; - current++; - } - return false; - } - - static bool ConsumeSubString(ref Iterator current, - Iterator end, - byte[] substring) - { - for (int i = 1; i < substring.Length; i++) - { - ++current; - if (current == end || current != substring[i]) - { - return false; - } - } - ++current; - return true; - } - - - // Consumes first character of the str is equal to ch - static bool ConsumeFirstCharacter(ref Iterator iter, - byte[] str, - int offset) - { - return iter.Value == str[offset]; - } - - static double SignedZero(bool sign) - { - return sign ? -0.0 : 0.0; - } - - static double StringToIeee( - Iterator input, - int length, - bool read_as_double, - out int processed_characters_count) - { - Iterator current = input; - Iterator end = input + length; - - processed_characters_count = 0; - - bool allow_trailing_junk = (flags_ & Flags.ALLOW_TRAILING_JUNK) != 0; - bool allow_leading_spaces = (flags_ & Flags.ALLOW_LEADING_SPACES) != 0; - bool allow_trailing_spaces = (flags_ & Flags.ALLOW_TRAILING_SPACES) != 0; - bool allow_spaces_after_sign = (flags_ & Flags.ALLOW_SPACES_AFTER_SIGN) != 0; - // bool allow_case_insensibility = (flags_ & Flags.ALLOW_CASE_INSENSIBILITY) != 0; - - // To make sure that iterator dereferencing is valid the following - // convention is used: - // 1. Each '++current' statement is followed by check for equality to 'end'. - // 2. If AdvanceToNonspace returned false then current == end. - // 3. If 'current' becomes equal to 'end' the function returns or goes to - // 'parsing_done'. - // 4. 'current' is not dereferenced after the 'parsing_done' label. - // 5. Code before 'parsing_done' may rely on 'current != end'. - if (length == 0) return empty_string_value_; - - if (allow_leading_spaces || allow_trailing_spaces) - { - if (!AdvanceToNonspace(ref current, end)) - { - processed_characters_count = (int)(current - input); - return empty_string_value_; - } - if (!allow_leading_spaces && (input != current)) - { - // No leading spaces allowed, but AdvanceToNonspace moved forward. - return junk_string_value_; - } - } - - // The longest form of simplified number is: "-.1eXXX\0". - byte[] buffer = GetBuffer(); // NOLINT: size is known at compile time. - int buffer_pos = 0; - - // Exponent will be adjusted if insignificant digits of the integer part - // or insignificant leading zeros of the fractional part are dropped. - int exponent = 0; - int significant_digits = 0; - int insignificant_digits = 0; - bool nonzero_digit_dropped = false; - - bool sign = false; - - if (current == '+' || current == '-') - { - sign = (current == '-'); - current++; - Iterator next_non_space = current; - // Skip following spaces (if allowed). - if (!AdvanceToNonspace(ref next_non_space, end)) return junk_string_value_; - if (!allow_spaces_after_sign && (current != next_non_space)) - { - return junk_string_value_; - } - current = next_non_space; - } - - if (infinity_symbol_ != null) - { - if (ConsumeFirstCharacter(ref current, infinity_symbol_, 0)) - { - if (!ConsumeSubString(ref current, end, infinity_symbol_)) - { - return junk_string_value_; - } - - if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) - { - return junk_string_value_; - } - if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) - { - return junk_string_value_; - } - - processed_characters_count = (current - input); - return sign ? double.NegativeInfinity : double.PositiveInfinity; - } - } - - if (nan_symbol_ != null) - { - if (ConsumeFirstCharacter(ref current, nan_symbol_, 0)) - { - if (!ConsumeSubString(ref current, end, nan_symbol_)) - { - return junk_string_value_; - } - - if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) - { - return junk_string_value_; - } - if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) - { - return junk_string_value_; - } - - processed_characters_count = (current - input); - return sign ? -double.NaN : double.NaN; - } - } - - bool leading_zero = false; - if (current == '0') - { - current++; - if (current == end) - { - processed_characters_count = (current - input); - return SignedZero(sign); - } - - leading_zero = true; - - // It could be hexadecimal value. - //if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) - //{ - // ++current; - // if (current == end || !isDigit(*current, 16)) - // { - // return junk_string_value_; // "0x". - // } - - // bool result_is_junk; - // double result = RadixStringToIeee < 4 > (¤t, - // end, - // sign, - // allow_trailing_junk, - // junk_string_value_, - // read_as_double, - // &result_is_junk); - // if (!result_is_junk) - // { - // if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); - // *processed_characters_count = static_cast(current - input); - // } - // return result; - //} - - // Ignore leading zeros in the integer part. - while (current == '0') - { - current++; - if (current == end) - { - processed_characters_count = (current - input); - return SignedZero(sign); - } - } - } - - bool octal = leading_zero && (flags_ & Flags.ALLOW_OCTALS) != 0; - - // Copy significant digits of the integer part (if any) to the buffer. - while (current >= '0' && current <= '9') - { - if (significant_digits < kMaxSignificantDigits) - { - buffer[buffer_pos++] = (current.Value); - significant_digits++; - // Will later check if it's an octal in the buffer. - } - else - { - insignificant_digits++; // Move the digit into the exponential part. - nonzero_digit_dropped = nonzero_digit_dropped || current != '0'; - } - // octal = octal && *current < '8'; - current++; - if (current == end) goto parsing_done; - } - - if (significant_digits == 0) - { - octal = false; - } - - if (current == '.') - { - if (octal && !allow_trailing_junk) return junk_string_value_; - if (octal) goto parsing_done; - - current++; - if (current == end) - { - if (significant_digits == 0 && !leading_zero) - { - return junk_string_value_; - } - else - { - goto parsing_done; - } - } - - if (significant_digits == 0) - { - // octal = false; - // Integer part consists of 0 or is absent. Significant digits start after - // leading zeros (if any). - while (current == '0') - { - ++current; - if (current == end) - { - processed_characters_count = (current - input); - return SignedZero(sign); - } - exponent--; // Move this 0 into the exponent. - } - } - - // There is a fractional part. - // We don't emit a '.', but adjust the exponent instead. - while (current >= '0' && current <= '9') - { - if (significant_digits < kMaxSignificantDigits) - { - buffer[buffer_pos++] = current.Value; - significant_digits++; - exponent--; - } - else - { - // Ignore insignificant digits in the fractional part. - nonzero_digit_dropped = nonzero_digit_dropped || current != '0'; - } - ++current; - if (current == end) goto parsing_done; - } - } - - if (!leading_zero && exponent == 0 && significant_digits == 0) - { - // If leading_zeros is true then the string contains zeros. - // If exponent < 0 then string was [+-]\.0*... - // If significant_digits != 0 the string is not equal to 0. - // Otherwise there are no digits in the string. - return junk_string_value_; - } - - // Parse exponential part. - if (current == 'e' || current == 'E') - { - if (octal && !allow_trailing_junk) return junk_string_value_; - if (octal) goto parsing_done; - ++current; - if (current == end) - { - if (allow_trailing_junk) - { - goto parsing_done; - } - else - { - return junk_string_value_; - } - } - byte exponen_sign = (byte)'+'; - if (current == '+' || current == '-') - { - exponen_sign = current.Value; - ++current; - if (current == end) - { - if (allow_trailing_junk) - { - goto parsing_done; - } - else - { - return junk_string_value_; - } - } - } - - if (current == end || current < '0' || current > '9') - { - if (allow_trailing_junk) - { - goto parsing_done; - } - else - { - return junk_string_value_; - } - } - - const int max_exponent = int.MaxValue / 2; - - int num = 0; - do - { - // Check overflow. - int digit = current.Value - (byte)'0'; - if (num >= max_exponent / 10 - && !(num == max_exponent / 10 && digit <= max_exponent % 10)) - { - num = max_exponent; - } - else - { - num = num * 10 + digit; - } - ++current; - } while (current != end && current >= '0' && current <= '9'); - - exponent += (exponen_sign == '-' ? -num : num); - } - - if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) - { - return junk_string_value_; - } - if (!allow_trailing_junk && AdvanceToNonspace(ref current, end)) - { - return junk_string_value_; - } - if (allow_trailing_spaces) - { - AdvanceToNonspace(ref current, end); - } - - parsing_done: - exponent += insignificant_digits; - - //if (octal) - //{ - // double result; - // bool result_is_junk; - // char* start = buffer; - // result = RadixStringToIeee < 3 > (&start, - // buffer + buffer_pos, - // sign, - // allow_trailing_junk, - // junk_string_value_, - // read_as_double, - // &result_is_junk); - // ASSERT(!result_is_junk); - // *processed_characters_count = static_cast(current - input); - // return result; - //} - - if (nonzero_digit_dropped) - { - buffer[buffer_pos++] = (byte)'1'; - exponent--; - } - - buffer[buffer_pos] = (byte)'\0'; - - double? converted; - if (read_as_double) - { - converted = StringToDouble.Strtod(new Vector(buffer, 0, buffer_pos), exponent); - } - else - { - converted = StringToDouble.Strtof(new Vector(buffer, 0, buffer_pos), exponent); - } - - if (converted == null) - { - // read-again - processed_characters_count = (current - input); - - var fallbackbuffer = GetFallbackBuffer(); - if (fallbackBuffer.Length < processed_characters_count) - { - Array.Resize(ref fallbackBuffer, processed_characters_count); - } - var fallbackI = 0; - while (input != current) - { - fallbackbuffer[fallbackI++] = input.Value; - input++; - } - var laststr = Encoding.UTF8.GetString(fallbackbuffer, 0, fallbackI); - return double.Parse(laststr); - } - - processed_characters_count = (current - input); - return sign ? -converted.Value : converted.Value; - } - } -} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs.meta deleted file mode 100644 index 5ab0b499..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/DoubleConversion/StringToDoubleConverter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3f829391169baba4294e8a24ddf0fc24 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs b/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs deleted file mode 100644 index f6dc0ef3..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Shims/Shims.cs +++ /dev/null @@ -1,483 +0,0 @@ -using Cysharp.Text.Internal; -using System; -using System.Runtime.CompilerServices; -using System.Text; - -namespace Cysharp.Text -{ - internal static class Int32 - { - /// 0 ~ 9 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsNumber(char c) - { - return '0' <= c && c <= '9'; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Parse(ReadOnlySpan s) - { - var value = 0L; - var sign = 1; - - if (s[0] == '-') - { - sign = -1; - } - - for (int i = ((sign == -1) ? 1 : 0); i < s.Length; i++) - { - if (!IsNumber(s[i])) - { - goto END; - } - - // long.MinValue causes overflow so use unchecked. - value = unchecked(value * 10 + ((byte)s[i] - '0')); - } - - END: - return checked((int)(unchecked(value * sign))); - } - } - - public static class ShimsExtensions - { - public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan span, Span bytes) - { - if (span.Length == 0) return 0; - fixed (char* src = span) - fixed (byte* dest = bytes) - { - return encoding.GetBytes(src, span.Length, dest, bytes.Length); - } - } - - public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return DoubleToStringConverter.TryFormat(destination, value, out charsWritten); - } - - public static bool TryFormat(this System.Double value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return DoubleToStringConverter.TryFormat(destination, value, out charsWritten); - } - - public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.DateTime value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.DateTimeOffset value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } - } - - public static bool TryFormat(this System.SByte value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteUInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteUInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteUInt64(destination, out charsWritten, value); - } - - public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) - { - return TryWriteUInt64(destination, out charsWritten, value); - } - - static string GetFormat(ReadOnlySpan format) - { - if (format.Length == 0) - { - return null; - } - return format.ToString(); - } - - static bool TryWriteInt64(Span buffer, out int charsWritten, long value) - { - var offset = 0; - charsWritten = 0; - long num1 = value, num2, num3, num4, num5, div; - - if (value < 0) - { - if (value == long.MinValue) // -9223372036854775808 - { - if (buffer.Length < 20) { return false; } - buffer[offset++] = (char)'-'; - buffer[offset++] = (char)'9'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'2'; - buffer[offset++] = (char)'0'; - buffer[offset++] = (char)'3'; - buffer[offset++] = (char)'6'; - buffer[offset++] = (char)'8'; - buffer[offset++] = (char)'5'; - buffer[offset++] = (char)'4'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'7'; - buffer[offset++] = (char)'5'; - buffer[offset++] = (char)'8'; - buffer[offset++] = (char)'0'; - buffer[offset++] = (char)'8'; - charsWritten = offset; - return true; - } - - if (buffer.Length < 1) { return false; } - buffer[offset++] = (char)'-'; - num1 = unchecked(-value); - } - - // WriteUInt64(inlined) - - if (num1 < 10000) - { - if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } - if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } - if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } - if (buffer.Length < 4) { return false; } - goto L4; - } - else - { - num2 = num1 / 10000; - num1 -= num2 * 10000; - if (num2 < 10000) - { - if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } - if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } - if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } - if (buffer.Length < 8) { return false; } - goto L8; - } - else - { - num3 = num2 / 10000; - num2 -= num3 * 10000; - if (num3 < 10000) - { - if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } - if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } - if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } - if (buffer.Length < 12) { return false; } - goto L12; - } - else - { - num4 = num3 / 10000; - num3 -= num4 * 10000; - if (num4 < 10000) - { - if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } - if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } - if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } - if (buffer.Length < 16) { return false; } - goto L16; - } - else - { - num5 = num4 / 10000; - num4 -= num5 * 10000; - if (num5 < 10000) - { - if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } - if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } - if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } - if (buffer.Length < 20) { return false; } - goto L20; - } - L20: - buffer[offset++] = (char)('0' + (div = (num5 * 8389L) >> 23)); - num5 -= div * 1000; - L19: - buffer[offset++] = (char)('0' + (div = (num5 * 5243L) >> 19)); - num5 -= div * 100; - L18: - buffer[offset++] = (char)('0' + (div = (num5 * 6554L) >> 16)); - num5 -= div * 10; - L17: - buffer[offset++] = (char)('0' + (num5)); - } - L16: - buffer[offset++] = (char)('0' + (div = (num4 * 8389L) >> 23)); - num4 -= div * 1000; - L15: - buffer[offset++] = (char)('0' + (div = (num4 * 5243L) >> 19)); - num4 -= div * 100; - L14: - buffer[offset++] = (char)('0' + (div = (num4 * 6554L) >> 16)); - num4 -= div * 10; - L13: - buffer[offset++] = (char)('0' + (num4)); - } - L12: - buffer[offset++] = (char)('0' + (div = (num3 * 8389L) >> 23)); - num3 -= div * 1000; - L11: - buffer[offset++] = (char)('0' + (div = (num3 * 5243L) >> 19)); - num3 -= div * 100; - L10: - buffer[offset++] = (char)('0' + (div = (num3 * 6554L) >> 16)); - num3 -= div * 10; - L9: - buffer[offset++] = (char)('0' + (num3)); - } - L8: - buffer[offset++] = (char)('0' + (div = (num2 * 8389L) >> 23)); - num2 -= div * 1000; - L7: - buffer[offset++] = (char)('0' + (div = (num2 * 5243L) >> 19)); - num2 -= div * 100; - L6: - buffer[offset++] = (char)('0' + (div = (num2 * 6554L) >> 16)); - num2 -= div * 10; - L5: - buffer[offset++] = (char)('0' + (num2)); - } - L4: - buffer[offset++] = (char)('0' + (div = (num1 * 8389L) >> 23)); - num1 -= div * 1000; - L3: - buffer[offset++] = (char)('0' + (div = (num1 * 5243L) >> 19)); - num1 -= div * 100; - L2: - buffer[offset++] = (char)('0' + (div = (num1 * 6554L) >> 16)); - num1 -= div * 10; - L1: - buffer[offset++] = (char)('0' + (num1)); - - charsWritten = offset; - return true; - } - - static bool TryWriteUInt64(Span buffer, out int charsWritten, ulong value) - { - ulong num1 = value, num2, num3, num4, num5, div; - charsWritten = 0; - var offset = 0; - - if (num1 < 10000) - { - if (num1 < 10) { if (buffer.Length < 1) { return false; } goto L1; } - if (num1 < 100) { if (buffer.Length < 2) { return false; } goto L2; } - if (num1 < 1000) { if (buffer.Length < 3) { return false; } goto L3; } - if (buffer.Length < 4) { return false; } - goto L4; - } - else - { - num2 = num1 / 10000; - num1 -= num2 * 10000; - if (num2 < 10000) - { - if (num2 < 10) { if (buffer.Length < 5) { return false; } goto L5; } - if (num2 < 100) { if (buffer.Length < 6) { return false; } goto L6; } - if (num2 < 1000) { if (buffer.Length < 7) { return false; } goto L7; } - if (buffer.Length < 8) { return false; } - goto L8; - } - else - { - num3 = num2 / 10000; - num2 -= num3 * 10000; - if (num3 < 10000) - { - if (num3 < 10) { if (buffer.Length < 9) { return false; } goto L9; } - if (num3 < 100) { if (buffer.Length < 10) { return false; } goto L10; } - if (num3 < 1000) { if (buffer.Length < 11) { return false; } goto L11; } - if (buffer.Length < 12) { return false; } - goto L12; - } - else - { - num4 = num3 / 10000; - num3 -= num4 * 10000; - if (num4 < 10000) - { - if (num4 < 10) { if (buffer.Length < 13) { return false; } goto L13; } - if (num4 < 100) { if (buffer.Length < 14) { return false; } goto L14; } - if (num4 < 1000) { if (buffer.Length < 15) { return false; } goto L15; } - if (buffer.Length < 16) { return false; } - goto L16; - } - else - { - num5 = num4 / 10000; - num4 -= num5 * 10000; - if (num5 < 10000) - { - if (num5 < 10) { if (buffer.Length < 17) { return false; } goto L17; } - if (num5 < 100) { if (buffer.Length < 18) { return false; } goto L18; } - if (num5 < 1000) { if (buffer.Length < 19) { return false; } goto L19; } - if (buffer.Length < 20) { return false; } - goto L20; - } - L20: - buffer[offset++] = (char)('0' + (div = (num5 * 8389UL) >> 23)); - num5 -= div * 1000; - L19: - buffer[offset++] = (char)('0' + (div = (num5 * 5243UL) >> 19)); - num5 -= div * 100; - L18: - buffer[offset++] = (char)('0' + (div = (num5 * 6554UL) >> 16)); - num5 -= div * 10; - L17: - buffer[offset++] = (char)('0' + (num5)); - } - L16: - buffer[offset++] = (char)('0' + (div = (num4 * 8389UL) >> 23)); - num4 -= div * 1000; - L15: - buffer[offset++] = (char)('0' + (div = (num4 * 5243UL) >> 19)); - num4 -= div * 100; - L14: - buffer[offset++] = (char)('0' + (div = (num4 * 6554UL) >> 16)); - num4 -= div * 10; - L13: - buffer[offset++] = (char)('0' + (num4)); - } - L12: - buffer[offset++] = (char)('0' + (div = (num3 * 8389UL) >> 23)); - num3 -= div * 1000; - L11: - buffer[offset++] = (char)('0' + (div = (num3 * 5243UL) >> 19)); - num3 -= div * 100; - L10: - buffer[offset++] = (char)('0' + (div = (num3 * 6554UL) >> 16)); - num3 -= div * 10; - L9: - buffer[offset++] = (char)('0' + (num3)); - } - L8: - buffer[offset++] = (char)('0' + (div = (num2 * 8389UL) >> 23)); - num2 -= div * 1000; - L7: - buffer[offset++] = (char)('0' + (div = (num2 * 5243UL) >> 19)); - num2 -= div * 100; - L6: - buffer[offset++] = (char)('0' + (div = (num2 * 6554UL) >> 16)); - num2 -= div * 10; - L5: - buffer[offset++] = (char)('0' + (num2)); - } - L4: - buffer[offset++] = (char)('0' + (div = (num1 * 8389UL) >> 23)); - num1 -= div * 1000; - L3: - buffer[offset++] = (char)('0' + (div = (num1 * 5243UL) >> 19)); - num1 -= div * 100; - L2: - buffer[offset++] = (char)('0' + (div = (num1 * 6554UL) >> 16)); - num1 -= div * 10; - L1: - buffer[offset++] = (char)('0' + (num1)); - - charsWritten = offset; - return true; - } - } -} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs new file mode 100644 index 00000000..47b425e1 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs @@ -0,0 +1,14 @@ +using System; +using TMPro; + +namespace Cysharp.Text +{ + public static partial class TextMeshProExtensions + { + public static void SetText(this TMP_Text text, Utf16ValueStringBuilder stringBuilder) + { + var array = stringBuilder.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs index cbb7f1e7..93c8f6e6 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs @@ -3,13 +3,13 @@ namespace Cysharp.Text { - public static class TextMeshProExtensions + public static partial class TextMeshProExtensions { public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -18,9 +18,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -29,9 +29,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 a public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -40,9 +40,9 @@ public static void SetTextFormat(this TMP_Text text, string format, public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -51,9 +51,9 @@ public static void SetTextFormat(this TMP_Text text, string form public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -62,9 +62,9 @@ public static void SetTextFormat(this TMP_Text text, string public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -73,9 +73,9 @@ public static void SetTextFormat(this TMP_Text text, str public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -84,9 +84,9 @@ public static void SetTextFormat(this TMP_Text text, public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -95,9 +95,9 @@ public static void SetTextFormat(this TMP_Text t public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -106,9 +106,9 @@ public static void SetTextFormat(this TMP_Te public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -117,9 +117,9 @@ public static void SetTextFormat(this TM public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -128,9 +128,9 @@ public static void SetTextFormat(th public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -139,9 +139,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -150,9 +150,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -161,9 +161,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -172,9 +172,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 5182c93b..21140b8d 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -45,7 +45,7 @@ public void AppendFormat(string format, T0 arg0) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -138,7 +138,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -151,7 +151,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -244,7 +244,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -257,7 +257,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -270,7 +270,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -363,7 +363,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -376,7 +376,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -389,7 +389,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -402,7 +402,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -495,7 +495,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -508,7 +508,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -521,7 +521,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -534,7 +534,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -547,7 +547,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -640,7 +640,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -653,7 +653,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -666,7 +666,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -679,7 +679,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -692,7 +692,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -705,7 +705,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -798,7 +798,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -811,7 +811,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -824,7 +824,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -837,7 +837,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -850,7 +850,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -863,7 +863,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -876,7 +876,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -969,7 +969,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -982,7 +982,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -995,7 +995,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1008,7 +1008,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1021,7 +1021,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1034,7 +1034,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1047,7 +1047,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1060,7 +1060,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1153,7 +1153,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -1166,7 +1166,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -1179,7 +1179,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1192,7 +1192,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1205,7 +1205,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1218,7 +1218,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1231,7 +1231,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1244,7 +1244,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1257,7 +1257,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -1350,7 +1350,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -1363,7 +1363,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -1376,7 +1376,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1389,7 +1389,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1402,7 +1402,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1415,7 +1415,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1428,7 +1428,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1441,7 +1441,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1454,7 +1454,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -1467,7 +1467,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -1560,7 +1560,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -1573,7 +1573,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -1586,7 +1586,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1599,7 +1599,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1612,7 +1612,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1625,7 +1625,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1638,7 +1638,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1651,7 +1651,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1664,7 +1664,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -1677,7 +1677,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -1690,7 +1690,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -1783,7 +1783,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -1796,7 +1796,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -1809,7 +1809,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1822,7 +1822,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1835,7 +1835,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1848,7 +1848,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1861,7 +1861,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1874,7 +1874,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1887,7 +1887,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -1900,7 +1900,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -1913,7 +1913,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -1926,7 +1926,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2019,7 +2019,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -2032,7 +2032,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -2045,7 +2045,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -2058,7 +2058,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -2071,7 +2071,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -2084,7 +2084,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -2097,7 +2097,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -2110,7 +2110,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -2123,7 +2123,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -2136,7 +2136,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -2149,7 +2149,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -2162,7 +2162,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2175,7 +2175,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg12)); @@ -2268,7 +2268,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -2281,7 +2281,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -2294,7 +2294,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -2307,7 +2307,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -2320,7 +2320,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -2333,7 +2333,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -2346,7 +2346,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -2359,7 +2359,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -2372,7 +2372,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -2385,7 +2385,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -2398,7 +2398,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -2411,7 +2411,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2424,7 +2424,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg12)); @@ -2437,7 +2437,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg13)); @@ -2530,7 +2530,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -2543,7 +2543,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -2556,7 +2556,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -2569,7 +2569,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -2582,7 +2582,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -2595,7 +2595,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -2608,7 +2608,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -2621,7 +2621,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -2634,7 +2634,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -2647,7 +2647,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -2660,7 +2660,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -2673,7 +2673,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2686,7 +2686,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg12)); @@ -2699,7 +2699,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg13)); @@ -2712,7 +2712,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg14)); @@ -2805,7 +2805,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -2818,7 +2818,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -2831,7 +2831,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -2844,7 +2844,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -2857,7 +2857,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -2870,7 +2870,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -2883,7 +2883,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -2896,7 +2896,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -2909,7 +2909,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -2922,7 +2922,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -2935,7 +2935,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -2948,7 +2948,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2961,7 +2961,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg12)); @@ -2974,7 +2974,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg13)); @@ -2987,7 +2987,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg14)); @@ -3000,7 +3000,7 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg15)); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs.meta new file mode 100644 index 00000000..eab064ae --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb0f0bec1ae6dc84e9e42b7490a9a9ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index 0c7eaad5..06d14d57 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -20,12 +20,12 @@ public void Append(System.Byte value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Byte value, ReadOnlySpan format) + public void Append(System.Byte value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -48,12 +48,12 @@ public void Append(System.DateTime value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTime value, ReadOnlySpan format) + public void Append(System.DateTime value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -76,12 +76,12 @@ public void Append(System.DateTimeOffset value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTimeOffset value, ReadOnlySpan format) + public void Append(System.DateTimeOffset value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -104,12 +104,12 @@ public void Append(System.Decimal value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Decimal value, ReadOnlySpan format) + public void Append(System.Decimal value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -132,12 +132,12 @@ public void Append(System.Double value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Double value, ReadOnlySpan format) + public void Append(System.Double value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -160,12 +160,12 @@ public void Append(System.Int16 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int16 value, ReadOnlySpan format) + public void Append(System.Int16 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -188,12 +188,12 @@ public void Append(System.Int32 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int32 value, ReadOnlySpan format) + public void Append(System.Int32 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -216,12 +216,12 @@ public void Append(System.Int64 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int64 value, ReadOnlySpan format) + public void Append(System.Int64 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -244,12 +244,12 @@ public void Append(System.SByte value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.SByte value, ReadOnlySpan format) + public void Append(System.SByte value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -272,12 +272,12 @@ public void Append(System.Single value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Single value, ReadOnlySpan format) + public void Append(System.Single value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -300,12 +300,12 @@ public void Append(System.TimeSpan value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.TimeSpan value, ReadOnlySpan format) + public void Append(System.TimeSpan value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -328,12 +328,12 @@ public void Append(System.UInt16 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt16 value, ReadOnlySpan format) + public void Append(System.UInt16 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -356,12 +356,12 @@ public void Append(System.UInt32 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt32 value, ReadOnlySpan format) + public void Append(System.UInt32 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -384,12 +384,12 @@ public void Append(System.UInt64 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt64 value, ReadOnlySpan format) + public void Append(System.UInt64 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -412,12 +412,12 @@ public void Append(System.Guid value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Guid value, ReadOnlySpan format) + public void Append(System.Guid value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index c2181024..b7f22d46 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -76,11 +76,6 @@ public void Dispose() index = 0; } - public void Clear() - { - index = 0; - } - void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index 334abc75..2060e11c 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -45,7 +45,7 @@ public void AppendFormat(string format, T0 arg0) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -134,7 +134,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -147,7 +147,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -236,7 +236,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -249,7 +249,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -262,7 +262,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -351,7 +351,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -364,7 +364,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -377,7 +377,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -390,7 +390,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -479,7 +479,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -492,7 +492,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -505,7 +505,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -518,7 +518,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -531,7 +531,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -620,7 +620,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -633,7 +633,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -646,7 +646,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -659,7 +659,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -672,7 +672,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -685,7 +685,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -774,7 +774,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -787,7 +787,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -800,7 +800,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -813,7 +813,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -826,7 +826,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -839,7 +839,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -852,7 +852,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -941,7 +941,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -954,7 +954,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -967,7 +967,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -980,7 +980,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -993,7 +993,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1006,7 +1006,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1019,7 +1019,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1032,7 +1032,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1121,7 +1121,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1134,7 +1134,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1147,7 +1147,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -1160,7 +1160,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -1173,7 +1173,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1186,7 +1186,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1199,7 +1199,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1212,7 +1212,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1225,7 +1225,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -1314,7 +1314,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1327,7 +1327,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1340,7 +1340,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -1353,7 +1353,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -1366,7 +1366,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1379,7 +1379,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1392,7 +1392,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1405,7 +1405,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1418,7 +1418,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -1431,7 +1431,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -1520,7 +1520,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1533,7 +1533,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1546,7 +1546,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -1559,7 +1559,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -1572,7 +1572,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1585,7 +1585,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1598,7 +1598,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1611,7 +1611,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1624,7 +1624,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -1637,7 +1637,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -1650,7 +1650,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -1739,7 +1739,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1752,7 +1752,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1765,7 +1765,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -1778,7 +1778,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -1791,7 +1791,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1804,7 +1804,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1817,7 +1817,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1830,7 +1830,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1843,7 +1843,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -1856,7 +1856,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -1869,7 +1869,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -1882,7 +1882,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -1971,7 +1971,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1984,7 +1984,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1997,7 +1997,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -2010,7 +2010,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -2023,7 +2023,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -2036,7 +2036,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -2049,7 +2049,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -2062,7 +2062,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -2075,7 +2075,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -2088,7 +2088,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -2101,7 +2101,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -2114,7 +2114,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -2127,7 +2127,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); @@ -2216,7 +2216,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -2229,7 +2229,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -2242,7 +2242,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -2255,7 +2255,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -2268,7 +2268,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -2281,7 +2281,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -2294,7 +2294,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -2307,7 +2307,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -2320,7 +2320,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -2333,7 +2333,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -2346,7 +2346,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -2359,7 +2359,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -2372,7 +2372,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); @@ -2385,7 +2385,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); @@ -2474,7 +2474,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -2487,7 +2487,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -2500,7 +2500,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -2513,7 +2513,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -2526,7 +2526,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -2539,7 +2539,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -2552,7 +2552,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -2565,7 +2565,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -2578,7 +2578,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -2591,7 +2591,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -2604,7 +2604,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -2617,7 +2617,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -2630,7 +2630,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); @@ -2643,7 +2643,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); @@ -2656,7 +2656,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg14)); @@ -2745,7 +2745,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -2758,7 +2758,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -2771,7 +2771,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -2784,7 +2784,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -2797,7 +2797,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -2810,7 +2810,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -2823,7 +2823,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -2836,7 +2836,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -2849,7 +2849,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -2862,7 +2862,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -2875,7 +2875,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -2888,7 +2888,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -2901,7 +2901,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); @@ -2914,7 +2914,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); @@ -2927,7 +2927,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg14)); @@ -2940,7 +2940,7 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg15)); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs.meta new file mode 100644 index 00000000..007ce4a4 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cda5ff4533e0a854a8d5c19084a2a730 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs.meta new file mode 100644 index 00000000..45f4df8e --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3cc4c8c9a298173488ac495332e11009 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 33c62086..3108f4a2 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace Cysharp.Text { @@ -52,7 +53,7 @@ public static string Join(char separator, IEnumerable values) var sb = new Utf8ValueStringBuilder(true); try { - var isFirst = false; + var isFirst = true; foreach (var item in values) { if (!isFirst) @@ -61,7 +62,7 @@ public static string Join(char separator, IEnumerable values) } else { - isFirst = true; + isFirst = false; } sb.Append(item); } @@ -100,7 +101,7 @@ public static string Join(string separator, IEnumerable values) var sb = new Utf8ValueStringBuilder(true); try { - var isFirst = false; + var isFirst = true; foreach (var item in values) { if (!isFirst) @@ -109,7 +110,7 @@ public static string Join(string separator, IEnumerable values) } else { - isFirst = true; + isFirst = false; } sb.Append(item); } diff --git a/src/ZString/Number/GuidEx.cs b/src/ZString/Number/GuidEx.cs new file mode 100644 index 00000000..7444a5e0 --- /dev/null +++ b/src/ZString/Number/GuidEx.cs @@ -0,0 +1,170 @@ +using System.Runtime.InteropServices; + +namespace System +{ + [StructLayout(LayoutKind.Sequential)] + internal struct GuidEx + { + private int _a; // Do not rename (binary serialization) + private short _b; // Do not rename (binary serialization) + private short _c; // Do not rename (binary serialization) + private byte _d; // Do not rename (binary serialization) + private byte _e; // Do not rename (binary serialization) + private byte _f; // Do not rename (binary serialization) + private byte _g; // Do not rename (binary serialization) + private byte _h; // Do not rename (binary serialization) + private byte _i; // Do not rename (binary serialization) + private byte _j; // Do not rename (binary serialization) + private byte _k; // Do not rename (binary serialization) + + private static unsafe int HexsToChars(char* guidChars, int a, int b) + { + guidChars[0] = HexConverter.ToCharLower(a >> 4); + guidChars[1] = HexConverter.ToCharLower(a); + + guidChars[2] = HexConverter.ToCharLower(b >> 4); + guidChars[3] = HexConverter.ToCharLower(b); + + return 4; + } + + private static unsafe int HexsToCharsHexOutput(char* guidChars, int a, int b) + { + guidChars[0] = '0'; + guidChars[1] = 'x'; + + guidChars[2] = HexConverter.ToCharLower(a >> 4); + guidChars[3] = HexConverter.ToCharLower(a); + + guidChars[4] = ','; + guidChars[5] = '0'; + guidChars[6] = 'x'; + + guidChars[7] = HexConverter.ToCharLower(b >> 4); + guidChars[8] = HexConverter.ToCharLower(b); + + return 9; + } + + public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format = default) + { + if (format.Length == 0) + { + format = "D".AsSpan(); + } + // all acceptable format strings are of length 1 + if (format.Length != 1) + { + throw new FormatException("InvalidGuidFormatSpecification"); + } + + bool dash = true; + bool hex = false; + int braces = 0; + + int guidSize; + + switch (format[0]) + { + case 'D': + case 'd': + guidSize = 36; + break; + case 'N': + case 'n': + dash = false; + guidSize = 32; + break; + case 'B': + case 'b': + braces = '{' + ('}' << 16); + guidSize = 38; + break; + case 'P': + case 'p': + braces = '(' + (')' << 16); + guidSize = 38; + break; + case 'X': + case 'x': + braces = '{' + ('}' << 16); + dash = false; + hex = true; + guidSize = 68; + break; + default: + throw new FormatException("InvalidGuidFormatSpecification"); + } + + if (destination.Length < guidSize) + { + charsWritten = 0; + return false; + } + + unsafe + { + fixed (char* guidChars = &MemoryMarshal.GetReference(destination)) + { + char* p = guidChars; + + if (braces != 0) + *p++ = (char)braces; + + if (hex) + { + // {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}} + *p++ = '0'; + *p++ = 'x'; + p += HexsToChars(p, _a >> 24, _a >> 16); + p += HexsToChars(p, _a >> 8, _a); + *p++ = ','; + *p++ = '0'; + *p++ = 'x'; + p += HexsToChars(p, _b >> 8, _b); + *p++ = ','; + *p++ = '0'; + *p++ = 'x'; + p += HexsToChars(p, _c >> 8, _c); + *p++ = ','; + *p++ = '{'; + p += HexsToCharsHexOutput(p, _d, _e); + *p++ = ','; + p += HexsToCharsHexOutput(p, _f, _g); + *p++ = ','; + p += HexsToCharsHexOutput(p, _h, _i); + *p++ = ','; + p += HexsToCharsHexOutput(p, _j, _k); + *p++ = '}'; + } + else + { + // [{|(]dddddddd[-]dddd[-]dddd[-]dddd[-]dddddddddddd[}|)] + p += HexsToChars(p, _a >> 24, _a >> 16); + p += HexsToChars(p, _a >> 8, _a); + if (dash) + *p++ = '-'; + p += HexsToChars(p, _b >> 8, _b); + if (dash) + *p++ = '-'; + p += HexsToChars(p, _c >> 8, _c); + if (dash) + *p++ = '-'; + p += HexsToChars(p, _d, _e); + if (dash) + *p++ = '-'; + p += HexsToChars(p, _f, _g); + p += HexsToChars(p, _h, _i); + p += HexsToChars(p, _j, _k); + } + + if (braces != 0) + *p++ = (char)(braces >> 16); + } + } + + charsWritten = guidSize; + return true; + } + } +} diff --git a/src/ZString/Number/HexConverter.cs b/src/ZString/Number/HexConverter.cs new file mode 100644 index 00000000..4e4e3a72 --- /dev/null +++ b/src/ZString/Number/HexConverter.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +namespace System +{ + internal static class HexConverter + { + public enum Casing : uint + { + // Output [ '0' .. '9' ] and [ 'A' .. 'F' ]. + Upper = 0, + + // Output [ '0' .. '9' ] and [ 'a' .. 'f' ]. + // This works because values in the range [ 0x30 .. 0x39 ] ([ '0' .. '9' ]) + // already have the 0x20 bit set, so ORing them with 0x20 is a no-op, + // while outputs in the range [ 0x41 .. 0x46 ] ([ 'A' .. 'F' ]) + // don't have the 0x20 bit set, so ORing them maps to + // [ 0x61 .. 0x66 ] ([ 'a' .. 'f' ]), which is what we want. + Lower = 0x2020U, + } + + // We want to pack the incoming byte into a single integer [ 0000 HHHH 0000 LLLL ], + // where HHHH and LLLL are the high and low nibbles of the incoming byte. Then + // subtract this integer from a constant minuend as shown below. + // + // [ 1000 1001 1000 1001 ] + // - [ 0000 HHHH 0000 LLLL ] + // ========================= + // [ *YYY **** *ZZZ **** ] + // + // The end result of this is that YYY is 0b000 if HHHH <= 9, and YYY is 0b111 if HHHH >= 10. + // Similarly, ZZZ is 0b000 if LLLL <= 9, and ZZZ is 0b111 if LLLL >= 10. + // (We don't care about the value of asterisked bits.) + // + // To turn a nibble in the range [ 0 .. 9 ] into hex, we calculate hex := nibble + 48 (ascii '0'). + // To turn a nibble in the range [ 10 .. 15 ] into hex, we calculate hex := nibble - 10 + 65 (ascii 'A'). + // => hex := nibble + 55. + // The difference in the starting ASCII offset is (55 - 48) = 7, depending on whether the nibble is <= 9 or >= 10. + // Since 7 is 0b111, this conveniently matches the YYY or ZZZ value computed during the earlier subtraction. + + // The commented out code below is code that directly implements the logic described above. + + // uint packedOriginalValues = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU); + // uint difference = 0x8989U - packedOriginalValues; + // uint add7Mask = (difference & 0x7070U) >> 4; // line YYY and ZZZ back up with the packed values + // uint packedResult = packedOriginalValues + add7Mask + 0x3030U /* ascii '0' */; + + // The code below is equivalent to the commented out code above but has been tweaked + // to allow codegen to make some extra optimizations. + + // The low byte of the packed result contains the hex representation of the incoming byte's low nibble. + // The adjacent byte of the packed result contains the hex representation of the incoming byte's high nibble. + + // Finally, write to the output buffer starting with the *highest* index so that codegen can + // elide all but the first bounds check. (This only works if 'startingIndex' is a compile-time constant.) + + // The JIT can elide bounds checks if 'startingIndex' is constant and if the caller is + // writing to a span of known length (or the caller has already checked the bounds of the + // furthest access). + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ToBytesBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) + { + uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; + uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; + + buffer[startingIndex + 1] = (byte)packedResult; + buffer[startingIndex] = (byte)(packedResult >> 8); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ToCharsBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) + { + uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; + uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; + + buffer[startingIndex + 1] = (char)(packedResult & 0xFF); + buffer[startingIndex] = (char)(packedResult >> 8); + } + + public static unsafe string ToString(ReadOnlySpan bytes, Casing casing = Casing.Upper) + { + Span result = stackalloc char[0]; + if (bytes.Length > 16) + { + var array = new char[bytes.Length * 2]; + result = array.AsSpan(); + } + else + { + result = stackalloc char[bytes.Length * 2]; + } + + int pos = 0; + foreach (byte b in bytes) + { + ToCharsBuffer(b, result, pos, casing); + pos += 2; + } + return result.ToString(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char ToCharUpper(int value) + { + value &= 0xF; + value += '0'; + + if (value > '9') + { + value += ('A' - ('9' + 1)); + } + + return (char)value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static char ToCharLower(int value) + { + value &= 0xF; + value += '0'; + + if (value > '9') + { + value += ('a' - ('9' + 1)); + } + + return (char)value; + } + } +} \ No newline at end of file diff --git a/src/ZString/Shims.cs b/src/ZString/Shims.cs index 00651657..6dd01f74 100644 --- a/src/ZString/Shims.cs +++ b/src/ZString/Shims.cs @@ -1,7 +1,8 @@ -using System; +#if !NETSTANDARD2_1 + +using System; using System.Globalization; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Text; namespace Cysharp.Text @@ -54,27 +55,9 @@ public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan spa } } - - - - - - - public static bool TryFormat(this System.Guid value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } + return Unsafe.As(ref value).TryFormat(destination, out charsWritten, format); } public static bool TryFormat(this System.TimeSpan value, Span destination, out int charsWritten, ReadOnlySpan format = default) @@ -127,18 +110,7 @@ public static bool TryFormat(this System.DateTimeOffset value, Span destin public static bool TryFormat(this System.Decimal value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - var f = GetFormat(format); - var span = ((f == null) ? value.ToString() : value.ToString(f)).AsSpan(); - if (span.TryCopyTo(destination)) - { - charsWritten = span.Length; - return true; - } - else - { - charsWritten = 0; - return false; - } + return Number.TryFormatDecimal(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); } public static bool TryFormat(this System.Single value, Span destination, out int charsWritten, ReadOnlySpan format = default) @@ -170,37 +142,91 @@ public static bool TryFormat(this System.SByte value, Span destination, ou public static bool TryFormat(this System.Int16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - return TryWriteInt64(destination, out charsWritten, value); + if (format.Length == 0) + { + return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); + } + else + { + if (value < 0 && format.Length > 0 && (format[0] == 'X' || format[0] == 'x')) + { + uint temp = (uint)(value & 0x0000FFFF); + return Number.TryFormatUInt32(temp, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } + return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } } public static bool TryFormat(this System.Int32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - return TryWriteInt64(destination, out charsWritten, value); + if (format.Length == 0) + { + return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } } public static bool TryFormat(this System.Int64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - return TryWriteInt64(destination, out charsWritten, value); + if (format.Length == 0) + { + return FastNumberWriter.TryWriteInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatInt64(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } } public static bool TryFormat(this System.Byte value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - return TryWriteUInt64(destination, out charsWritten, value); + if (format.Length == 0) + { + return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } } public static bool TryFormat(this System.UInt16 value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - return TryWriteUInt64(destination, out charsWritten, value); + if (format.Length == 0) + { + return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } } public static bool TryFormat(this System.UInt32 value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - return TryWriteUInt64(destination, out charsWritten, value); + if (format.Length == 0) + { + return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatUInt32(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } } public static bool TryFormat(this System.UInt64 value, Span destination, out int charsWritten, ReadOnlySpan format = default) { - return TryWriteUInt64(destination, out charsWritten, value); + if (format.Length == 0) + { + return FastNumberWriter.TryWriteUInt64(destination, out charsWritten, value); + } + else + { + return Number.TryFormatUInt64(value, format, NumberFormatInfo.CurrentInfo, destination, out charsWritten); + } } static string GetFormat(ReadOnlySpan format) @@ -214,3 +240,5 @@ static string GetFormat(ReadOnlySpan format) } } } + +#endif \ No newline at end of file diff --git a/src/ZString/Unity/TextMeshProExtensions.cs b/src/ZString/Unity/TextMeshProExtensions.cs index cbb7f1e7..93c8f6e6 100644 --- a/src/ZString/Unity/TextMeshProExtensions.cs +++ b/src/ZString/Unity/TextMeshProExtensions.cs @@ -3,13 +3,13 @@ namespace Cysharp.Text { - public static class TextMeshProExtensions + public static partial class TextMeshProExtensions { public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -18,9 +18,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -29,9 +29,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 a public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -40,9 +40,9 @@ public static void SetTextFormat(this TMP_Text text, string format, public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -51,9 +51,9 @@ public static void SetTextFormat(this TMP_Text text, string form public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -62,9 +62,9 @@ public static void SetTextFormat(this TMP_Text text, string public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -73,9 +73,9 @@ public static void SetTextFormat(this TMP_Text text, str public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -84,9 +84,9 @@ public static void SetTextFormat(this TMP_Text text, public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -95,9 +95,9 @@ public static void SetTextFormat(this TMP_Text t public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -106,9 +106,9 @@ public static void SetTextFormat(this TMP_Te public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -117,9 +117,9 @@ public static void SetTextFormat(this TM public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -128,9 +128,9 @@ public static void SetTextFormat(th public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -139,9 +139,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -150,9 +150,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -161,9 +161,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); @@ -172,9 +172,9 @@ public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); + sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); diff --git a/src/ZString/Unity/TextMeshProExtensions.tt b/src/ZString/Unity/TextMeshProExtensions.tt index 3491e92d..23ba548c 100644 --- a/src/ZString/Unity/TextMeshProExtensions.tt +++ b/src/ZString/Unity/TextMeshProExtensions.tt @@ -31,9 +31,8 @@ namespace Cysharp.Text <# for(var i = 1; i <= 16; i++) { #> public static void SetTextFormat<<#= CreateTypeArgument(i) #>>(this TMP_Text text, string format, <#= CreateParameters(i) #>) { - using (var sb = new Cysharp.Text.Utf16ValueStringBuilder()) + using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) { - sb.Init(true); sb.AppendFormat(format, <#= CreateParameterNames(i) #>); var array = sb.AsArraySegment(); text.SetCharArray(array.Array, array.Offset, array.Count); diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 5182c93b..21140b8d 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -45,7 +45,7 @@ public void AppendFormat(string format, T0 arg0) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -138,7 +138,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -151,7 +151,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -244,7 +244,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -257,7 +257,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -270,7 +270,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -363,7 +363,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -376,7 +376,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -389,7 +389,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -402,7 +402,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -495,7 +495,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -508,7 +508,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -521,7 +521,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -534,7 +534,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -547,7 +547,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -640,7 +640,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -653,7 +653,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -666,7 +666,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -679,7 +679,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -692,7 +692,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -705,7 +705,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -798,7 +798,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -811,7 +811,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -824,7 +824,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -837,7 +837,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -850,7 +850,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -863,7 +863,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -876,7 +876,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -969,7 +969,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -982,7 +982,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -995,7 +995,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1008,7 +1008,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1021,7 +1021,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1034,7 +1034,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1047,7 +1047,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1060,7 +1060,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1153,7 +1153,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -1166,7 +1166,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -1179,7 +1179,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1192,7 +1192,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1205,7 +1205,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1218,7 +1218,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1231,7 +1231,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1244,7 +1244,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1257,7 +1257,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -1350,7 +1350,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -1363,7 +1363,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -1376,7 +1376,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1389,7 +1389,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1402,7 +1402,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1415,7 +1415,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1428,7 +1428,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1441,7 +1441,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1454,7 +1454,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -1467,7 +1467,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -1560,7 +1560,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -1573,7 +1573,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -1586,7 +1586,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1599,7 +1599,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1612,7 +1612,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1625,7 +1625,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1638,7 +1638,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1651,7 +1651,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1664,7 +1664,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -1677,7 +1677,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -1690,7 +1690,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -1783,7 +1783,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -1796,7 +1796,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -1809,7 +1809,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -1822,7 +1822,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -1835,7 +1835,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -1848,7 +1848,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -1861,7 +1861,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -1874,7 +1874,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -1887,7 +1887,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -1900,7 +1900,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -1913,7 +1913,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -1926,7 +1926,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2019,7 +2019,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -2032,7 +2032,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -2045,7 +2045,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -2058,7 +2058,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -2071,7 +2071,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -2084,7 +2084,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -2097,7 +2097,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -2110,7 +2110,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -2123,7 +2123,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -2136,7 +2136,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -2149,7 +2149,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -2162,7 +2162,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2175,7 +2175,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg12)); @@ -2268,7 +2268,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -2281,7 +2281,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -2294,7 +2294,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -2307,7 +2307,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -2320,7 +2320,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -2333,7 +2333,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -2346,7 +2346,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -2359,7 +2359,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -2372,7 +2372,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -2385,7 +2385,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -2398,7 +2398,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -2411,7 +2411,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2424,7 +2424,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg12)); @@ -2437,7 +2437,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg13)); @@ -2530,7 +2530,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -2543,7 +2543,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -2556,7 +2556,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -2569,7 +2569,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -2582,7 +2582,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -2595,7 +2595,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -2608,7 +2608,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -2621,7 +2621,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -2634,7 +2634,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -2647,7 +2647,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -2660,7 +2660,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -2673,7 +2673,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2686,7 +2686,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg12)); @@ -2699,7 +2699,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg13)); @@ -2712,7 +2712,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg14)); @@ -2805,7 +2805,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg0)); @@ -2818,7 +2818,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg1)); @@ -2831,7 +2831,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg2)); @@ -2844,7 +2844,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg3)); @@ -2857,7 +2857,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg4)); @@ -2870,7 +2870,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg5)); @@ -2883,7 +2883,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg6)); @@ -2896,7 +2896,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg7)); @@ -2909,7 +2909,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg8)); @@ -2922,7 +2922,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg9)); @@ -2935,7 +2935,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg10)); @@ -2948,7 +2948,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg11)); @@ -2961,7 +2961,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg12)); @@ -2974,7 +2974,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg13)); @@ -2987,7 +2987,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg14)); @@ -3000,7 +3000,7 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg15)); diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt index 32be60d4..1e760313 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt @@ -70,7 +70,7 @@ namespace Cysharp.Text { if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out var written, indexParse.FormatString)) { - Grow(); + Grow(written); if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, indexParse.FormatString)) { ThrowArgumentException(nameof(arg<#= j #>)); diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index 0c7eaad5..06d14d57 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -20,12 +20,12 @@ public void Append(System.Byte value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Byte value, ReadOnlySpan format) + public void Append(System.Byte value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -48,12 +48,12 @@ public void Append(System.DateTime value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTime value, ReadOnlySpan format) + public void Append(System.DateTime value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -76,12 +76,12 @@ public void Append(System.DateTimeOffset value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.DateTimeOffset value, ReadOnlySpan format) + public void Append(System.DateTimeOffset value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -104,12 +104,12 @@ public void Append(System.Decimal value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Decimal value, ReadOnlySpan format) + public void Append(System.Decimal value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -132,12 +132,12 @@ public void Append(System.Double value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Double value, ReadOnlySpan format) + public void Append(System.Double value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -160,12 +160,12 @@ public void Append(System.Int16 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int16 value, ReadOnlySpan format) + public void Append(System.Int16 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -188,12 +188,12 @@ public void Append(System.Int32 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int32 value, ReadOnlySpan format) + public void Append(System.Int32 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -216,12 +216,12 @@ public void Append(System.Int64 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Int64 value, ReadOnlySpan format) + public void Append(System.Int64 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -244,12 +244,12 @@ public void Append(System.SByte value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.SByte value, ReadOnlySpan format) + public void Append(System.SByte value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -272,12 +272,12 @@ public void Append(System.Single value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Single value, ReadOnlySpan format) + public void Append(System.Single value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -300,12 +300,12 @@ public void Append(System.TimeSpan value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.TimeSpan value, ReadOnlySpan format) + public void Append(System.TimeSpan value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -328,12 +328,12 @@ public void Append(System.UInt16 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt16 value, ReadOnlySpan format) + public void Append(System.UInt16 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -356,12 +356,12 @@ public void Append(System.UInt32 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt32 value, ReadOnlySpan format) + public void Append(System.UInt32 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -384,12 +384,12 @@ public void Append(System.UInt64 value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.UInt64 value, ReadOnlySpan format) + public void Append(System.UInt64 value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } @@ -412,12 +412,12 @@ public void Append(System.Guid value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(System.Guid value, ReadOnlySpan format) + public void Append(System.Guid value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt index 7776e1a4..47477c05 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt @@ -48,12 +48,12 @@ namespace Cysharp.Text } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(<#= t.FullName #> value, ReadOnlySpan format) + public void Append(<#= t.FullName #> value, string format) { - if(!value.TryFormat(buffer.AsSpan(index), out var written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { Grow(); - if(!value.TryFormat(buffer.AsSpan(index), out written, format)) + if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); } diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index c2181024..f77ad572 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -4,7 +4,7 @@ namespace Cysharp.Text { - public partial struct Utf16ValueStringBuilder : IDisposable + public partial struct Utf16ValueStringBuilder : IDisposable, IBufferWriter { public delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); @@ -76,11 +76,6 @@ public void Dispose() index = 0; } - public void Clear() - { - index = 0; - } - void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) @@ -202,9 +197,19 @@ public override string ToString() return new string(buffer, 0, index); } - // IBufferWriter like interface. + // IBufferWriter + + public Memory GetMemory(int sizeHint) + { + if ((buffer.Length - index) < sizeHint) + { + Grow(sizeHint); + } + + return buffer.AsMemory(index); + } - public Span GetWritableBuffer(int sizeHint = 0) + public Span GetSpan(int sizeHint) { if ((buffer.Length - index) < sizeHint) { diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index 334abc75..2060e11c 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -45,7 +45,7 @@ public void AppendFormat(string format, T0 arg0) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -134,7 +134,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -147,7 +147,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -236,7 +236,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -249,7 +249,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -262,7 +262,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -351,7 +351,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -364,7 +364,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -377,7 +377,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -390,7 +390,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -479,7 +479,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -492,7 +492,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -505,7 +505,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -518,7 +518,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -531,7 +531,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -620,7 +620,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -633,7 +633,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -646,7 +646,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -659,7 +659,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -672,7 +672,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -685,7 +685,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -774,7 +774,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -787,7 +787,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -800,7 +800,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -813,7 +813,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -826,7 +826,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -839,7 +839,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -852,7 +852,7 @@ public void AppendFormat(string format, T0 arg0, T1 { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -941,7 +941,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -954,7 +954,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -967,7 +967,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -980,7 +980,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -993,7 +993,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1006,7 +1006,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1019,7 +1019,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1032,7 +1032,7 @@ public void AppendFormat(string format, T0 arg0, { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1121,7 +1121,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1134,7 +1134,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1147,7 +1147,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -1160,7 +1160,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -1173,7 +1173,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1186,7 +1186,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1199,7 +1199,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1212,7 +1212,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1225,7 +1225,7 @@ public void AppendFormat(string format, T0 a { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -1314,7 +1314,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1327,7 +1327,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1340,7 +1340,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -1353,7 +1353,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -1366,7 +1366,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1379,7 +1379,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1392,7 +1392,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1405,7 +1405,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1418,7 +1418,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -1431,7 +1431,7 @@ public void AppendFormat(string format, { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -1520,7 +1520,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1533,7 +1533,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1546,7 +1546,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -1559,7 +1559,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -1572,7 +1572,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1585,7 +1585,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1598,7 +1598,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1611,7 +1611,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1624,7 +1624,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -1637,7 +1637,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -1650,7 +1650,7 @@ public void AppendFormat(string for { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -1739,7 +1739,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1752,7 +1752,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1765,7 +1765,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -1778,7 +1778,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -1791,7 +1791,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -1804,7 +1804,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -1817,7 +1817,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -1830,7 +1830,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -1843,7 +1843,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -1856,7 +1856,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -1869,7 +1869,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -1882,7 +1882,7 @@ public void AppendFormat(strin { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -1971,7 +1971,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -1984,7 +1984,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -1997,7 +1997,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -2010,7 +2010,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -2023,7 +2023,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -2036,7 +2036,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -2049,7 +2049,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -2062,7 +2062,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -2075,7 +2075,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -2088,7 +2088,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -2101,7 +2101,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -2114,7 +2114,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -2127,7 +2127,7 @@ public void AppendFormat( { if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); @@ -2216,7 +2216,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -2229,7 +2229,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -2242,7 +2242,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -2255,7 +2255,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -2268,7 +2268,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -2281,7 +2281,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -2294,7 +2294,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -2307,7 +2307,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -2320,7 +2320,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -2333,7 +2333,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -2346,7 +2346,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -2359,7 +2359,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -2372,7 +2372,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); @@ -2385,7 +2385,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); @@ -2474,7 +2474,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -2487,7 +2487,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -2500,7 +2500,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -2513,7 +2513,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -2526,7 +2526,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -2539,7 +2539,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -2552,7 +2552,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -2565,7 +2565,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -2578,7 +2578,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -2591,7 +2591,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -2604,7 +2604,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -2617,7 +2617,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -2630,7 +2630,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); @@ -2643,7 +2643,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); @@ -2656,7 +2656,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg14)); @@ -2745,7 +2745,7 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg0)); @@ -2758,7 +2758,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg1)); @@ -2771,7 +2771,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg2)); @@ -2784,7 +2784,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg3)); @@ -2797,7 +2797,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg4)); @@ -2810,7 +2810,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg5)); @@ -2823,7 +2823,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg6)); @@ -2836,7 +2836,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg7)); @@ -2849,7 +2849,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg8)); @@ -2862,7 +2862,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg9)); @@ -2875,7 +2875,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg10)); @@ -2888,7 +2888,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg11)); @@ -2901,7 +2901,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg12)); @@ -2914,7 +2914,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg13)); @@ -2927,7 +2927,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg14)); @@ -2940,7 +2940,7 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg15)); diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt index 1e7efbc5..d288f8c1 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt @@ -70,7 +70,7 @@ namespace Cysharp.Text { if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out var written, writeFormat)) { - Grow(); + Grow(written); if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, writeFormat)) { ThrowArgumentException(nameof(arg<#= j #>)); diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 935f38af..3bd8f443 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -7,7 +7,7 @@ namespace Cysharp.Text { - public partial struct Utf8ValueStringBuilder : IDisposable + public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter { public delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); @@ -45,6 +45,8 @@ static Utf8ValueStringBuilder() public int Length => index; public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf8ValueStringBuilder(bool disposeImmediately) @@ -209,9 +211,19 @@ public override string ToString() return UTF8NoBom.GetString(buffer, 0, index); } - // IBufferWriter like interface. + // IBufferWriter - public Span GetWritableBuffer(int sizeHint = 0) + public Memory GetMemory(int sizeHint) + { + if ((buffer.Length - index) < sizeHint) + { + Grow(sizeHint); + } + + return buffer.AsMemory(index); + } + + public Span GetSpan(int sizeHint) { if ((buffer.Length - index) < sizeHint) { diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 33c62086..d7a46c66 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace Cysharp.Text { @@ -47,12 +48,33 @@ public static string Join(char separator, params T[] values) } } + public static string Join(char separator, ReadOnlySpan values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + public static string Join(char separator, IEnumerable values) { var sb = new Utf8ValueStringBuilder(true); try { - var isFirst = false; + var isFirst = true; foreach (var item in values) { if (!isFirst) @@ -61,7 +83,7 @@ public static string Join(char separator, IEnumerable values) } else { - isFirst = true; + isFirst = false; } sb.Append(item); } @@ -95,12 +117,33 @@ public static string Join(string separator, params T[] values) } } + public static string Join(string separator, ReadOnlySpan values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + public static string Join(string separator, IEnumerable values) { var sb = new Utf8ValueStringBuilder(true); try { - var isFirst = false; + var isFirst = true; foreach (var item in values) { if (!isFirst) @@ -109,7 +152,7 @@ public static string Join(string separator, IEnumerable values) } else { - isFirst = true; + isFirst = false; } sb.Append(item); } diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 3470ddd3..8d42f575 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -22,23 +22,23 @@ - + - TextTemplatingFileGenerator - TextMeshProExtensions.cs + TextTemplatingFileGenerator + TextMeshProExtensions.cs Utf16ValueStringBuilder.AppendMany.cs TextTemplatingFileGenerator - TextTemplatingFileGenerator - Utf16ValueStringBuilder.Concat.cs + TextTemplatingFileGenerator + Utf16ValueStringBuilder.Concat.cs Utf16ValueStringBuilder.CreateFormatter.cs @@ -57,8 +57,8 @@ TextTemplatingFileGenerator - TextTemplatingFileGenerator - Utf8ValueStringBuilder.Concat.cs + TextTemplatingFileGenerator + Utf8ValueStringBuilder.Concat.cs Utf8ValueStringBuilder.CreateFormatter.cs @@ -73,8 +73,8 @@ Utf16ValueStringBuilder.AppendFormat.cs - TextTemplatingFileGenerator - ZString.Concat.cs + TextTemplatingFileGenerator + ZString.Concat.cs TextTemplatingFileGenerator @@ -94,9 +94,9 @@ True - True - True - Utf16ValueStringBuilder.Concat.tt + True + True + Utf16ValueStringBuilder.Concat.tt Utf16ValueStringBuilder.CreateFormatter.tt @@ -119,9 +119,9 @@ Utf8ValueStringBuilder.AppendMany.tt - True - True - Utf8ValueStringBuilder.Concat.tt + True + True + Utf8ValueStringBuilder.Concat.tt True @@ -134,9 +134,9 @@ Utf8ValueStringBuilder.SpanFormattableAppend.tt - True - True - ZString.Concat.tt + True + True + ZString.Concat.tt True @@ -156,10 +156,6 @@ - - - - diff --git a/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj b/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj index 0f797485..ae89ff5a 100644 --- a/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj +++ b/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj @@ -9,6 +9,7 @@ + all diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index 052ec015..d8e30d2c 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -68,11 +68,7 @@ public void Comment() [Fact] public void FormatArgs() { -#if NETCOREAPP3_1 ZString.Format("{0:00000000}-{1:00000000}", 100, 200).Should().Be("00000100-00000200"); -#else - ZString.Format("{0:00000000}-{1:00000000}", 100, 200).Should().Be("100-200"); -#endif } } } \ No newline at end of file diff --git a/tests/ZString.Tests/JoinTest.cs b/tests/ZString.Tests/JoinTest.cs new file mode 100644 index 00000000..12463d51 --- /dev/null +++ b/tests/ZString.Tests/JoinTest.cs @@ -0,0 +1,37 @@ +using Cysharp.Text; +using FluentAssertions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public class JoinTest + { + [Fact] + public void JoinOverloads() + { + ZString.Join("_,_", new string[0]).Should().Be(string.Join("_,_", new string[0])); + ZString.Join("_,_", new[] { 1 }).Should().Be(string.Join("_,_", new[] { 1 })); + ZString.Join("_,_", new[] { 1, 2 }).Should().Be(string.Join("_,_", new[] { 1, 2 })); + ZString.Join("_,_", new[] { 1, 2, 3 }).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); + + ZString.Join("_,_", new string[] { }.AsEnumerable()).Should().Be(string.Join("_,_", new string[0])); + ZString.Join("_,_", new[] { 1 }.AsEnumerable()).Should().Be(string.Join("_,_", new[] { 1 })); + ZString.Join("_,_", new[] { 1, 2 }.AsEnumerable()).Should().Be(string.Join("_,_", new[] { 1, 2 })); + ZString.Join("_,_", new[] { 1, 2, 3 }.AsEnumerable()).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); + + ZString.Join(',', new string[0]).Should().Be(string.Join(",", new string[0])); + ZString.Join(',', new[] { 1 }).Should().Be(string.Join(",", new[] { 1 })); + ZString.Join(',', new[] { 1, 2 }).Should().Be(string.Join(",", new[] { 1, 2 })); + ZString.Join(',', new[] { 1, 2, 3 }).Should().Be(string.Join(",", new[] { 1, 2, 3 })); + + ZString.Join(',', new string[0].AsEnumerable()).Should().Be(string.Join(",", new string[0])); + ZString.Join(',', new[] { 1 }.AsEnumerable()).Should().Be(string.Join(",", new[] { 1 })); + ZString.Join(',', new[] { 1, 2 }.AsEnumerable()).Should().Be(string.Join(",", new[] { 1, 2 })); + ZString.Join(',', new[] { 1, 2, 3 }.AsEnumerable()).Should().Be(string.Join(",", new[] { 1, 2, 3 })); + } + } +} From 42f8e50403c428285f0750d94d6e0e3cec5b5b13 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Fri, 14 Feb 2020 05:10:18 +0900 Subject: [PATCH 024/139] complete for 1.0 --- README.md | 148 +- docs/graph.xlsx | Bin 0 -> 15961 bytes sandbox/ConsoleApp/ConsoleApp.csproj | 1 + sandbox/ConsoleApp/Program.cs | 25 +- sandbox/ConsoleAppNet472/Program.cs | 5 + ...nchmark.cs => SixObjectConcatBenchmark.cs} | 46 +- ...eshProExtensions.SetStringBuilder.cs.meta} | 2 +- .../Utf16ValueStringBuilder.AppendFormat.cs | 112 +- ...f16ValueStringBuilder.AppendFormat.cs.meta | 2 +- .../Utf16ValueStringBuilder.AppendMany.cs | 1538 ----- ...Utf16ValueStringBuilder.AppendMany.cs.meta | 11 - .../Utf16/Utf16ValueStringBuilder.Concat.cs | 5609 ----------------- ...ValueStringBuilder.CreateFormatter.cs.meta | 2 +- ...alueStringBuilder.SpanFormattableAppend.cs | 255 + ...tringBuilder.SpanFormattableAppend.cs.meta | 2 +- .../ZString/Utf16ValueStringBuilder.cs | 51 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 112 +- ...tf8ValueStringBuilder.AppendFormat.cs.meta | 2 +- .../Utf8/Utf8ValueStringBuilder.AppendMany.cs | 1538 ----- .../Utf8ValueStringBuilder.AppendMany.cs.meta | 11 - .../Utf8/Utf8ValueStringBuilder.Concat.cs | 1576 ----- .../Utf8ValueStringBuilder.Concat.cs.meta | 11 - ...ValueStringBuilder.CreateFormatter.cs.meta | 2 +- ...alueStringBuilder.SpanFormattableAppend.cs | 255 + ...tringBuilder.SpanFormattableAppend.cs.meta | 2 +- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 60 +- .../Assets/Scripts/ZString/ZString.Concat.cs | 1816 +++++- .../Assets/Scripts/ZString/ZString.Format.cs | 16 + .../Assets/Scripts/ZString/ZString.cs | 52 + .../ProjectSettings/Physics2DSettings.asset | Bin 4448 -> 2028 bytes src/ZString.Unity/ZString.Unity.unitypackage | Bin 0 -> 183356 bytes .../Utf16ValueStringBuilder.AppendFormat.cs | 112 +- .../Utf16ValueStringBuilder.AppendFormat.tt | 12 +- .../Utf16/Utf16ValueStringBuilder.Concat.cs | 5609 ----------------- .../Utf16/Utf16ValueStringBuilder.Concat.tt | 86 - ...alueStringBuilder.SpanFormattableAppend.cs | 255 + ...alueStringBuilder.SpanFormattableAppend.tt | 17 + src/ZString/Utf16ValueStringBuilder.cs | 35 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 112 +- .../Utf8ValueStringBuilder.AppendFormat.tt | 7 +- .../Utf8/Utf8ValueStringBuilder.Concat.cs | 1576 ----- .../Utf8/Utf8ValueStringBuilder.Concat.tt | 58 - ...alueStringBuilder.SpanFormattableAppend.cs | 255 + ...alueStringBuilder.SpanFormattableAppend.tt | 17 + src/ZString/Utf8ValueStringBuilder.cs | 42 +- src/ZString/ZString.Concat.cs | 1816 +++++- src/ZString/ZString.Concat.tt | 23 +- src/ZString/ZString.Format.cs | 16 + src/ZString/ZString.Format.tt | 1 + src/ZString/ZString.cs | 10 + src/ZString/ZString.csproj | 21 +- tests/ZString.Tests/Primitives.cs | 22 +- 52 files changed, 5145 insertions(+), 18219 deletions(-) create mode 100644 docs/graph.xlsx rename sandbox/PerfBenchmark/Benchmarks/{FourObjectConcatBenchmark.cs => SixObjectConcatBenchmark.cs} (57%) rename src/ZString.Unity/Assets/Scripts/ZString/{Utf16/Utf16ValueStringBuilder.Concat.cs.meta => Unity/TextMeshProExtensions.SetStringBuilder.cs.meta} (83%) delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs.meta delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs.meta delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs delete mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs.meta create mode 100644 src/ZString.Unity/ZString.Unity.unitypackage delete mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs delete mode 100644 src/ZString/Utf16/Utf16ValueStringBuilder.Concat.tt delete mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs delete mode 100644 src/ZString/Utf8/Utf8ValueStringBuilder.Concat.tt diff --git a/README.md b/README.md index b8a87398..7bcd1bf5 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,20 @@ ZString * Can use inner buffer to avoid allocate final string * Can build both Utf16(`Span`) and Utf8(`Span`) directly -// ここに性能比較の画像を貼る +![image](https://user-images.githubusercontent.com/46207/74473217-9061e200-4ee6-11ea-9a77-14d740886faa.png) -// ここに普通のは何で遅いかの理由を書いておく +This graph compares following codes. + +* `"x:" + x + " y:" + y + " z:" + z` +* `ZString.Concat("x:", x, " y:", y, " z:", z)` +* `string.Format("x:{0} y:{1} z:{2}", x, y, z)` +* `ZString.Format("x:{0} y:{1} z:{2}", x, y, z)` +* `new StringBuilder(), Append(), .ToString()` +* `ZString.CreateStringBuilder(), Append(), .ToString()` + +`"x:" + x + " y:" + y + " z:" + z` is converted to `String.Concat(new []{ "x:", x.ToString(), " y:", y.ToString(), " z:", z.ToString() })` by C# compiler. It has each `.ToString` allocation and params array allocation. `string.Format` calls `String.Format(string, object, object, object)` so each arguments causes int -> object boxing. + +All `ZString` methods only allocate final string. Also, `ZString` has enabled to access inner buffer so if output target has stringless api, you can achieve completely zero allocation. Getting Started --- @@ -45,7 +56,6 @@ async void Example(int x, int y, int z) sb.Append("foo"); sb.AppendLine(42); sb.AppendFormat("{0} {1:.###}", "bar", 123.456789); - sb.Concat(1, "foo", 100, "bar"); // and build final string var str = sb.ToString(); @@ -64,56 +74,140 @@ async void Example(int x, int y, int z) sb2.Concat("foo:", x, ", bar:", y); // directly write to steam or dest to avoid allocation - await sb2.CopyToAsync(stream); + await sb2.WriteToAsync(stream); sb2.TryCopyTo(dest, out var written); } ``` Reference --- -ZString +**static class ZString** | method | returns | description | | -- | -- | -- | -| CreateStringBuilder | Utf16ValueStringBuilder | Create Utf16 string StringBuilder | -| CreateStringBuilder(bool notNested) | Utf16ValueStringBuilder | Create Utf16 string StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | -| CreateUtf8StringBuilder | Utf8ValueStringBuilder | Create Utf8(`Span`) StringBuilder | -| CreateUtf8StringBuilder(bool notNested) | Utf8ValueStringBuilder | Create Utf8(`Span`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | - +| CreateStringBuilder() | Utf16ValueStringBuilder | Create the Utf16 string StringBuilder. | +| CreateStringBuilder(bool notNested) | Utf16ValueStringBuilder | Create the Utf16 string StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | +| CreateUtf8StringBuilder() | Utf8ValueStringBuilder | Create the Utf8(`Span`) StringBuilder. | +| CreateUtf8StringBuilder(bool notNested) | Utf8ValueStringBuilder | Create the Utf8(`Span`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | +| `Join(char|string, T[]/IE)` | string | Concatenates the elements of an array, using the specified seperator between each element. | +| `Concat(T0,..,T15)` | string | Concatenates the string representation of some specified values. | +| `Format(string, T0,..,T15)` | string | Replaces one or more format items in a string with the string representation of some specified values. | -| Join | Utf8ValueStringBuilder | Create Utf8(`Span`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | +**struct Utf16ValueStringBuilder : `IBufferWriter`, IDisposable** +| method | returns | description | +| -- | -- | -- | +| Length | int | Length of written buffer. | +| AsSpan() | `ReadOnlySpan` | Get the written buffer data. | +| AsMemory() | `ReadOnlyMemory` | Get the written buffer data. | +| AsArraySegment() | `ArraySegment` | Get the written buffer data. | +| Dispose() | void | Return the inner buffer to pool. | +| `Append(T value)` | void | Appends the string representation of a specified value to this instance. | +| `Append(T value, string format)` | void | Appends the string representation of a specified value to this instance with numeric format strings. | +| `AppendLine()` | void | Appends the default line terminator to the end of this instance. | +| `AppendLine(T value)` | void | Appends the string representation of a specified value followed by the default line terminator to the end of this instance. | +| `AppendLine(T value, string format)` | void | Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. | +| `AppendFormat(string, T0,..,T15)` | void | Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. | +| `TryCopyTo(Span, out int)` | bool | Copy inner buffer to the destination span. | +| ToString() | string | Converts the value of this instance to a System.String. | +| GetMemory(int sizeHint) | `Memory` | IBufferWriter.GetMemory. | +| GetSpan(int sizeHint) | `Span` | IBufferWriter.GetSpan. | +| Advance(int count) | void | IBufferWriter.Advance. | +| static `RegisterTryFormat(TryFormat)` | void | Register custom formatter. | + +**struct Utf8ValueStringBuilder : `IBufferWriter`, IDisposable** +| method | returns | description | +| -- | -- | -- | +| Length | int | Length of written buffer. | +| AsSpan() | `ReadOnlySpan` | Get the written buffer data. | +| AsMemory() | `ReadOnlyMemory` | Get the written buffer data. | +| AsArraySegment() | `ArraySegment` | Get the written buffer data. | +| Dispose() | void | Return the inner buffer to pool. | +| `Append(T value)` | void | Appends the string representation of a specified value to this instance. | +| `Append(T value, StandardFormat format)` | void | Appends the string representation of a specified value to this instance with numeric format strings. | +| `AppendLine()` | void | Appends the default line terminator to the end of this instance. | +| `AppendLine(T value)` | void | Appends the string representation of a specified value followed by the default line terminator to the end of this instance. | +| `AppendLine(T value, StandardFormat format)` | void | Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. | +| `AppendFormat(string, T0,..,T15)` | void | Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. | +| `TryCopyTo(Span, out int)` | bool | Copy inner buffer to the destination span. | +| WriteToAsync(Stream stream) | Task | Write inner buffer to stream. | +| ToString() | string | Encode the innner utf8 buffer to a System.String. | +| GetMemory(int sizeHint) | `Memory` | IBufferWriter.GetMemory. | +| GetSpan(int sizeHint) | `Span` | IBufferWriter.GetSpan. | +| Advance(int count) | void | IBufferWriter.Advance. | +| static `RegisterTryFormat(TryFormat)` | void | Register custom formatter. | + +**static class TextMeshProExtensions**(Unity only) +| method | returns | description | +| -- | -- | -- | +| SetText(Utf16ValueStringBuilder) | void | Set inner buffer to text mesh pro directly to avoid string allocation. | +| `SetTextFormat(string, T0,..,T15)` | void | Set formatted string without string allocation. | +Advanced Tips +--- +`ZString.CreateStringBuilder(notNested:true)` is a special optimized parameter that uses `ThreadStatic` buffer instead of rent from `ArrayPool`. It is slightly faster but can not use in nested. +```csharp +using(var sb = ZString.CreateStringBuilder(true)) +{ + sb.Append("foo"); -SetTextFormat is extension method of `TMP_Text`, there parameter is generics so can avoid boxing, and ZString writes to buffer directly without any ToString allocation. Finally inner buffer copy to `TextMeshPro` buffer so avoid all string allocations. + using var sb2 = ZString.CreateStringBuilder(true); // NG, nested stringbuilder uses conflicted same buffer + var str = ZString.Concat("x", 100); // NG, ZString.Concat/Join/Format uses threadstatic buffer +} +``` ```csharp -public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) -public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1) -// ... -public static void SetTextFormat(this TMP_Text text, string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) +// OK, return buffer immediately. +using(var sb = ZString.CreateStringBuilder(true)) +{ + sb.Append("foo"); + return sb.ToString(); +} ``` -Raw API is start from `ZString.CreateStringBuilder();`. +`ZString.CreateStringBuilder()` is same as `ZString.CreateStringBuilder(notNested:false)`. + +--- + +In default, `SByte`, `Int16`, `Int32`, `Int64`, `Byte`, `UInt16`, `UInt32`, `UInt64`, `Single`, `Double`, `TimeSpan`, `DateTime`, `DateTimeOffset`, `Decimal`, `Guid`, `String`, `Char` are used there own formatter to avoid `.ToString()` allocation, write directly to buffer. If not exists there list type, used `.ToString()` and copy string data. + +If you want to avoid to convert string in custom type, you can register your own formatter. ```csharp -using(var sb = ZString.CreateStringBuilder()) +Utf16ValueStringBuilder.RegisterTryFormat((MyStruct value, Span destination, out int charsWritten, ReadOnlySpan format) => { - sb.Append("foo"); - sb.AppendLine(42); - sb.AppendFormat("{0} {1}", "bar", 123.456); - sb.AppendMany(1, "foo", 100, "bar"); - - Debug.Log(sb.ToString()); -} + // write value to destionation and set size to charsWritten. + charsWritten = 0; + return true; +}); -// If you want to use only format, use `ZString.Format` instead of `String.Format`. -var str = ZString.Format("foo {0} bar {1}", 42, 123.456); +Utf8ValueStringBuilder.RegisterTryFormat((MyStruct value, Span destination, out int written, StandardFormat format) => +{ + written = 0; + return true; +}); ``` +--- + +`CreateStringBuilder` and `CreateUtf8StringBuilder` must use with `using`. Because their builder rent 64K buffer from `ArrayPool`. If not return buffer, allocate 64K buffer when string builder is created. + +--- + +`Utf8ValueStringBuilder` and `Utf16ValueStringBuilder` implements `IBufferWriter` so you can pass serializer(such as `JsonSerializer` of `System.Text.Json`). But be careful to boxing copy, `ValueStringBuilder` is mutable struct. For example, + +```csharp +using var sb = ZString.CreateUtf8StringBuilder(); +IBufferWriter boxed = sb; +var writer = new Utf8JsonWriter(boxed); +JsonSerializer.Serialize(writer, ....); + +using var unboxed = (Utf8ValueStringBuilder)boxed; +var str = unboxed.ToString(); +``` License --- diff --git a/docs/graph.xlsx b/docs/graph.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ada4266b20b214faa6dd560e6871e412ce79c09f GIT binary patch literal 15961 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 literal 0 HcmV?d00001 diff --git a/sandbox/ConsoleApp/ConsoleApp.csproj b/sandbox/ConsoleApp/ConsoleApp.csproj index ef582eea..db193179 100644 --- a/sandbox/ConsoleApp/ConsoleApp.csproj +++ b/sandbox/ConsoleApp/ConsoleApp.csproj @@ -7,6 +7,7 @@ + diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index 72e0a97a..49ad4fe2 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -1,11 +1,18 @@ using Cysharp.Text; using System; +using System.Buffers; using System.Linq; using System.Text; using System.Text.Formatting; +using System.Text.Json; namespace ConsoleApp { + public struct MyStruct + { + + } + class Program { static void Main(string[] args) @@ -15,15 +22,15 @@ static void Main(string[] args) static void Run() { - using (var sb = ZString.CreateStringBuilder()) - { - sb.Append("foo"); - sb.AppendLine(42); - sb.AppendFormat("{0} {1:.###}", "bar", 123.456789); - sb.Concat(1, "foo", 100, "bar"); - - Console.WriteLine(sb.ToString()); - } + using var sb = ZString.CreateUtf8StringBuilder(); + IBufferWriter boxed = sb; + var writer = new Utf8JsonWriter(boxed); + JsonSerializer.Serialize(writer, new { foo = 999 }); + + using var unboxed = (Utf8ValueStringBuilder)boxed; + + Console.WriteLine(sb.ToString()); + Console.WriteLine(unboxed.ToString()); } } diff --git a/sandbox/ConsoleAppNet472/Program.cs b/sandbox/ConsoleAppNet472/Program.cs index 6e5be66b..c801c8a9 100644 --- a/sandbox/ConsoleAppNet472/Program.cs +++ b/sandbox/ConsoleAppNet472/Program.cs @@ -13,6 +13,11 @@ static void Main(string[] args) { var x = ZString.CreateStringBuilder(); + var sb = new StringBuilder(); + + + + x.AppendFormat("hoge{0:.##}, tako{1:000}", 123.456, 9); Console.WriteLine(x.ToString()); diff --git a/sandbox/PerfBenchmark/Benchmarks/FourObjectConcatBenchmark.cs b/sandbox/PerfBenchmark/Benchmarks/SixObjectConcatBenchmark.cs similarity index 57% rename from sandbox/PerfBenchmark/Benchmarks/FourObjectConcatBenchmark.cs rename to sandbox/PerfBenchmark/Benchmarks/SixObjectConcatBenchmark.cs index 43ed472c..267ada62 100644 --- a/sandbox/PerfBenchmark/Benchmarks/FourObjectConcatBenchmark.cs +++ b/sandbox/PerfBenchmark/Benchmarks/SixObjectConcatBenchmark.cs @@ -1,69 +1,71 @@ using BenchmarkDotNet.Attributes; using Cysharp.Text; +using System; using System.Text; namespace PerfBenchmark.Benchmarks { [Config(typeof(BenchmarkConfig))] - public class FourObjectConcatBenchmark + public class SixObjectConcatBenchmark { int x; int y; + int z; - public FourObjectConcatBenchmark() + public SixObjectConcatBenchmark() { - x = int.Parse("100"); - y = int.Parse("200"); + x = int.Parse("333"); + y = int.Parse("444"); + z = int.Parse("555"); } [Benchmark] public string StringPlus() { - return "x:" + x + ", y:" + y; + return "x:" + x + " y:" + y + " z:" + z; } [Benchmark] - public string StringConcatObject() + public string ZStringConcat() { - return string.Concat("x:", x, ", y:", y); + return ZString.Concat("x:", x, " y:", y, " z:", z); } [Benchmark] - public string ZStringConcat() + public string StringFormat() { - return ZString.Concat("x:", x, ", y:", y); + return string.Format("x:{0} y:{1} z:{2}", x, y, z); } [Benchmark] - public string StringBuilder() + public string ZStringFormat() { - var sb = new StringBuilder(); - sb.Append("x:"); - sb.Append(x); - sb.Append(", y:"); - sb.Append(y); - return sb.ToString(); + return ZString.Format("x:{0} y:{1} z:{2}", x, y, z); } [Benchmark] - public string ZStringBuilder() + public string StringBuilder() { - using var sb = ZString.CreateStringBuilder(); + var sb = new StringBuilder(); sb.Append("x:"); sb.Append(x); - sb.Append(", y:"); + sb.Append(" y:"); sb.Append(y); + sb.Append(" z:"); + sb.Append(z); return sb.ToString(); } [Benchmark] - public string ZStringBuilder2() + public string ZStringBuilder() { - using var sb = ZString.CreateStringBuilder(true); + using var sb = ZString.CreateStringBuilder(); sb.Append("x:"); sb.Append(x); - sb.Append(", y:"); + sb.Append(" y:"); sb.Append(y); + sb.Append(" z:"); + sb.Append(z); return sb.ToString(); } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs.meta similarity index 83% rename from src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs.meta rename to src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs.meta index eab064ae..59aadc5b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.SetStringBuilder.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: bb0f0bec1ae6dc84e9e42b7490a9a9ca +guid: 26ef652c2e8c2cc488e0b2e063a179ce MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 21140b8d..6eae9735 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -4,6 +4,7 @@ namespace Cysharp.Text { public partial struct Utf16ValueStringBuilder { + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0) { var copyFrom = 0; @@ -91,12 +92,7 @@ public void AppendFormat(string format, T0 arg0) } } - public void AppendFormatLine(string format, T0 arg0) - { - AppendFormat(format, arg0); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1) { var copyFrom = 0; @@ -197,12 +193,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1) - { - AppendFormat(format, arg0, arg1); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { var copyFrom = 0; @@ -316,12 +307,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2) - { - AppendFormat(format, arg0, arg1, arg2); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; @@ -448,12 +434,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - AppendFormat(format, arg0, arg1, arg2, arg3); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; @@ -593,12 +574,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; @@ -751,12 +727,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; @@ -922,12 +893,7 @@ public void AppendFormat(string format, T0 arg0, T1 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; @@ -1106,12 +1072,7 @@ public void AppendFormat(string format, T0 arg0, } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; @@ -1303,12 +1264,7 @@ public void AppendFormat(string format, T0 a } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; @@ -1513,12 +1469,7 @@ public void AppendFormat(string format, } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; @@ -1736,12 +1687,7 @@ public void AppendFormat(string for } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; @@ -1972,12 +1918,7 @@ public void AppendFormat(strin } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; @@ -2221,12 +2162,7 @@ public void AppendFormat( } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; @@ -2483,12 +2419,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; @@ -2758,12 +2689,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; @@ -3046,11 +2972,5 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - } } \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta index 0f4556e7..fcbb76f0 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 939995818389d4748855b4f240115700 +guid: 2c686f65ca8d42c4aa85d157c378f10e MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs deleted file mode 100644 index e900deb4..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs +++ /dev/null @@ -1,1538 +0,0 @@ -using System; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { - public void AppendMany(T0 arg0, T1 arg1) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1) - { - AppendMany(arg0, arg1); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2) - { - AppendMany(arg0, arg1, arg2); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - AppendMany(arg0, arg1, arg2, arg3); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - AppendMany(arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - - } -} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs.meta deleted file mode 100644 index 6058e64e..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendMany.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d025cae7956cb8f4387c9f69827872cf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs deleted file mode 100644 index 78c1169b..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs +++ /dev/null @@ -1,5609 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { - public void Concat(T0 arg0) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0) - { - Concat(arg0); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1) - { - Concat(arg0, arg1); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2) - { - Concat(arg0, arg1, arg2); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - Concat(arg0, arg1, arg2, arg3); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - Concat(arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - if (typeof(T12) == typeof(string)) - { - var s12 = Unsafe.As(ref arg12); - if (s12 != null) - { - TryGrow(s12.Length); - s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s12.Length; - } - } - else if (typeof(T12) == typeof(int)) - { - int written = 0; - - var i12 = Unsafe.As(ref arg12); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - if (typeof(T12) == typeof(string)) - { - var s12 = Unsafe.As(ref arg12); - if (s12 != null) - { - TryGrow(s12.Length); - s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s12.Length; - } - } - else if (typeof(T12) == typeof(int)) - { - int written = 0; - - var i12 = Unsafe.As(ref arg12); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - - if (typeof(T13) == typeof(string)) - { - var s13 = Unsafe.As(ref arg13); - if (s13 != null) - { - TryGrow(s13.Length); - s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s13.Length; - } - } - else if (typeof(T13) == typeof(int)) - { - int written = 0; - - var i13 = Unsafe.As(ref arg13); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - if (typeof(T12) == typeof(string)) - { - var s12 = Unsafe.As(ref arg12); - if (s12 != null) - { - TryGrow(s12.Length); - s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s12.Length; - } - } - else if (typeof(T12) == typeof(int)) - { - int written = 0; - - var i12 = Unsafe.As(ref arg12); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - - if (typeof(T13) == typeof(string)) - { - var s13 = Unsafe.As(ref arg13); - if (s13 != null) - { - TryGrow(s13.Length); - s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s13.Length; - } - } - else if (typeof(T13) == typeof(int)) - { - int written = 0; - - var i13 = Unsafe.As(ref arg13); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - - if (typeof(T14) == typeof(string)) - { - var s14 = Unsafe.As(ref arg14); - if (s14 != null) - { - TryGrow(s14.Length); - s14.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s14.Length; - } - } - else if (typeof(T14) == typeof(int)) - { - int written = 0; - - var i14 = Unsafe.As(ref arg14); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - if (typeof(T12) == typeof(string)) - { - var s12 = Unsafe.As(ref arg12); - if (s12 != null) - { - TryGrow(s12.Length); - s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s12.Length; - } - } - else if (typeof(T12) == typeof(int)) - { - int written = 0; - - var i12 = Unsafe.As(ref arg12); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - - if (typeof(T13) == typeof(string)) - { - var s13 = Unsafe.As(ref arg13); - if (s13 != null) - { - TryGrow(s13.Length); - s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s13.Length; - } - } - else if (typeof(T13) == typeof(int)) - { - int written = 0; - - var i13 = Unsafe.As(ref arg13); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - - if (typeof(T14) == typeof(string)) - { - var s14 = Unsafe.As(ref arg14); - if (s14 != null) - { - TryGrow(s14.Length); - s14.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s14.Length; - } - } - else if (typeof(T14) == typeof(int)) - { - int written = 0; - - var i14 = Unsafe.As(ref arg14); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - } - - if (typeof(T15) == typeof(string)) - { - var s15 = Unsafe.As(ref arg15); - if (s15 != null) - { - TryGrow(s15.Length); - s15.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s15.Length; - } - } - else if (typeof(T15) == typeof(int)) - { - int written = 0; - - var i15 = Unsafe.As(ref arg15); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i15)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i15)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - - } -} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta index 4150f972..8ab90678 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e74b3448ff97ca644b3ecb70a63ae365 +guid: d81568aff3a79df41881112bb037c194 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index 06d14d57..29a6d10c 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -5,6 +5,7 @@ namespace Cysharp.Text { public partial struct Utf16ValueStringBuilder { + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) { @@ -19,6 +20,7 @@ public void Append(System.Byte value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value, string format) { @@ -33,6 +35,22 @@ public void Append(System.Byte value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Byte value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Byte value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value) { @@ -47,6 +65,7 @@ public void Append(System.DateTime value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value, string format) { @@ -61,6 +80,22 @@ public void Append(System.DateTime value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTime value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTime value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value) { @@ -75,6 +110,7 @@ public void Append(System.DateTimeOffset value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value, string format) { @@ -89,6 +125,22 @@ public void Append(System.DateTimeOffset value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTimeOffset value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTimeOffset value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value) { @@ -103,6 +155,7 @@ public void Append(System.Decimal value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value, string format) { @@ -117,6 +170,22 @@ public void Append(System.Decimal value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Decimal value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Decimal value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value) { @@ -131,6 +200,7 @@ public void Append(System.Double value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value, string format) { @@ -145,6 +215,22 @@ public void Append(System.Double value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Double value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Double value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value) { @@ -159,6 +245,7 @@ public void Append(System.Int16 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value, string format) { @@ -173,6 +260,22 @@ public void Append(System.Int16 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int16 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int16 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value) { @@ -187,6 +290,7 @@ public void Append(System.Int32 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value, string format) { @@ -201,6 +305,22 @@ public void Append(System.Int32 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int32 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int32 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value) { @@ -215,6 +335,7 @@ public void Append(System.Int64 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value, string format) { @@ -229,6 +350,22 @@ public void Append(System.Int64 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int64 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int64 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value) { @@ -243,6 +380,7 @@ public void Append(System.SByte value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value, string format) { @@ -257,6 +395,22 @@ public void Append(System.SByte value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.SByte value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.SByte value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value) { @@ -271,6 +425,7 @@ public void Append(System.Single value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value, string format) { @@ -285,6 +440,22 @@ public void Append(System.Single value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Single value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Single value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value) { @@ -299,6 +470,7 @@ public void Append(System.TimeSpan value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value, string format) { @@ -313,6 +485,22 @@ public void Append(System.TimeSpan value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.TimeSpan value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.TimeSpan value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value) { @@ -327,6 +515,7 @@ public void Append(System.UInt16 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value, string format) { @@ -341,6 +530,22 @@ public void Append(System.UInt16 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt16 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt16 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value) { @@ -355,6 +560,7 @@ public void Append(System.UInt32 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value, string format) { @@ -369,6 +575,22 @@ public void Append(System.UInt32 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt32 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt32 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value) { @@ -383,6 +605,7 @@ public void Append(System.UInt64 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value, string format) { @@ -397,6 +620,22 @@ public void Append(System.UInt64 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt64 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt64 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value) { @@ -411,6 +650,7 @@ public void Append(System.Guid value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value, string format) { @@ -425,5 +665,20 @@ public void Append(System.Guid value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Guid value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Guid value, string format) + { + Append(value, format); + AppendLine(); + } } } \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta index e7eb74b6..5ae630ba 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 84eb008280df72041a1f3f4fd7147292 +guid: 0143a9022d2d364409298fa82d0bbc01 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index b7f22d46..e20d28cb 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -4,7 +4,7 @@ namespace Cysharp.Text { - public partial struct Utf16ValueStringBuilder : IDisposable + public partial struct Utf16ValueStringBuilder : IDisposable, IBufferWriter { public delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); @@ -39,9 +39,13 @@ static Utf16ValueStringBuilder() char[] buffer; int index; + /// Length of written buffer. public int Length => index; + /// Get the written buffer data. public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + /// Get the written buffer data. public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + /// Get the written buffer data. public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -65,12 +69,18 @@ public Utf16ValueStringBuilder(bool disposeImmediately) index = 0; } + /// + /// Return the inner buffer to pool. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (buffer.Length != ThreadStaticBufferSize) { - ArrayPool.Shared.Return(buffer); + if (buffer != null) + { + ArrayPool.Shared.Return(buffer); + } } buffer = null; index = 0; @@ -103,8 +113,9 @@ void Grow(int sizeHint = 0) buffer = newBuffer; } + /// Appends the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendNewLine() + public void AppendLine() { if (crlf) { @@ -121,6 +132,7 @@ public void AppendNewLine() } } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(char value) { @@ -132,13 +144,15 @@ public void Append(char value) buffer[index++] = value; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(char value) { Append(value); - AppendNewLine(); + AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { @@ -151,13 +165,15 @@ public void Append(string value) index += value.Length; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(string value) { Append(value); - AppendNewLine(); + AppendLine(); } + /// Appends the string representation of a specified value to this instance. public void Append(T value) { if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) @@ -171,14 +187,16 @@ public void Append(T value) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. public void AppendLine(T value) { Append(value); - AppendNewLine(); + AppendLine(); } // Output + /// Copy inner buffer to the destination span. public bool TryCopyTo(Span destination, out int charsWritten) { if (destination.Length < index) @@ -192,14 +210,27 @@ public bool TryCopyTo(Span destination, out int charsWritten) return true; } + /// Converts the value of this instance to a System.String. public override string ToString() { return new string(buffer, 0, index); } - // IBufferWriter like interface. + // IBufferWriter + + /// IBufferWriter.GetMemory. + public Memory GetMemory(int sizeHint) + { + if ((buffer.Length - index) < sizeHint) + { + Grow(sizeHint); + } + + return buffer.AsMemory(index); + } - public Span GetWritableBuffer(int sizeHint = 0) + /// IBufferWriter.GetSpan. + public Span GetSpan(int sizeHint) { if ((buffer.Length - index) < sizeHint) { @@ -209,6 +240,7 @@ public Span GetWritableBuffer(int sizeHint = 0) return buffer.AsSpan(index); } + /// IBufferWriter.Advance. public void Advance(int count) { index += count; @@ -224,6 +256,9 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + /// + /// Register custom formatter + /// public static void RegisterTryFormat(TryFormat formatMethod) { FormatterCache.TryFormatDelegate = formatMethod; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index 2060e11c..b68e7d61 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -5,6 +5,7 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder { + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0) { var copyFrom = 0; @@ -88,12 +89,7 @@ public void AppendFormat(string format, T0 arg0) } } - public void AppendFormatLine(string format, T0 arg0) - { - AppendFormat(format, arg0); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1) { var copyFrom = 0; @@ -190,12 +186,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1) - { - AppendFormat(format, arg0, arg1); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { var copyFrom = 0; @@ -305,12 +296,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2) - { - AppendFormat(format, arg0, arg1, arg2); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; @@ -433,12 +419,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - AppendFormat(format, arg0, arg1, arg2, arg3); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; @@ -574,12 +555,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; @@ -728,12 +704,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; @@ -895,12 +866,7 @@ public void AppendFormat(string format, T0 arg0, T1 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; @@ -1075,12 +1041,7 @@ public void AppendFormat(string format, T0 arg0, } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; @@ -1268,12 +1229,7 @@ public void AppendFormat(string format, T0 a } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; @@ -1474,12 +1430,7 @@ public void AppendFormat(string format, } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; @@ -1693,12 +1644,7 @@ public void AppendFormat(string for } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; @@ -1925,12 +1871,7 @@ public void AppendFormat(strin } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; @@ -2170,12 +2111,7 @@ public void AppendFormat( } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; @@ -2428,12 +2364,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; @@ -2699,12 +2630,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; @@ -2983,11 +2909,5 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - } } \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta index 038b7555..3243019b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b0787c9daae5b314b8a42fc4d22309c2 +guid: 5d7ee057fcee1904f9ac7f3bf532a09e MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs deleted file mode 100644 index 30b9f992..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs +++ /dev/null @@ -1,1538 +0,0 @@ -using System; - -namespace Cysharp.Text -{ - public partial struct Utf8ValueStringBuilder - { - public void AppendMany(T0 arg0, T1 arg1) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1) - { - AppendMany(arg0, arg1); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2) - { - AppendMany(arg0, arg1, arg2); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - AppendMany(arg0, arg1, arg2, arg3); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - AppendMany(arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - - public void AppendMany(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - int written; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - - } - - public void AppendManyLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - AppendMany(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - - } -} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs.meta deleted file mode 100644 index ecb0b1e1..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendMany.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 47a4c76b9b48cd94ea1c8127f8ebe64f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs deleted file mode 100644 index 4ee6f9c9..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs +++ /dev/null @@ -1,1576 +0,0 @@ -using System; - -namespace Cysharp.Text -{ - public partial struct Utf8ValueStringBuilder - { - public void Concat(T0 arg0) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0) - { - Concat(arg0); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1) - { - Concat(arg0, arg1); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2) - { - Concat(arg0, arg1, arg2); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - Concat(arg0, arg1, arg2, arg3); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - Concat(arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg15, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - - } -} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs.meta deleted file mode 100644 index 007ce4a4..00000000 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cda5ff4533e0a854a8d5c19084a2a730 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta index c07954e8..221d361c 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ba965c020770010408b27ba8fa94fd12 +guid: 35e4f4117a41a70438f0ff051e65e239 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index bcf2135c..ecfef55d 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -7,6 +7,7 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder { + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) { @@ -21,6 +22,7 @@ public void Append(System.Byte value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value, StandardFormat format) { @@ -35,6 +37,22 @@ public void Append(System.Byte value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Byte value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Byte value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value) { @@ -49,6 +67,7 @@ public void Append(System.DateTime value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value, StandardFormat format) { @@ -63,6 +82,22 @@ public void Append(System.DateTime value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTime value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTime value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value) { @@ -77,6 +112,7 @@ public void Append(System.DateTimeOffset value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value, StandardFormat format) { @@ -91,6 +127,22 @@ public void Append(System.DateTimeOffset value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTimeOffset value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTimeOffset value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value) { @@ -105,6 +157,7 @@ public void Append(System.Decimal value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value, StandardFormat format) { @@ -119,6 +172,22 @@ public void Append(System.Decimal value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Decimal value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Decimal value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value) { @@ -133,6 +202,7 @@ public void Append(System.Double value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value, StandardFormat format) { @@ -147,6 +217,22 @@ public void Append(System.Double value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Double value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Double value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value) { @@ -161,6 +247,7 @@ public void Append(System.Int16 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value, StandardFormat format) { @@ -175,6 +262,22 @@ public void Append(System.Int16 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int16 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int16 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value) { @@ -189,6 +292,7 @@ public void Append(System.Int32 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value, StandardFormat format) { @@ -203,6 +307,22 @@ public void Append(System.Int32 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int32 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int32 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value) { @@ -217,6 +337,7 @@ public void Append(System.Int64 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value, StandardFormat format) { @@ -231,6 +352,22 @@ public void Append(System.Int64 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int64 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int64 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value) { @@ -245,6 +382,7 @@ public void Append(System.SByte value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value, StandardFormat format) { @@ -259,6 +397,22 @@ public void Append(System.SByte value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.SByte value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.SByte value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value) { @@ -273,6 +427,7 @@ public void Append(System.Single value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value, StandardFormat format) { @@ -287,6 +442,22 @@ public void Append(System.Single value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Single value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Single value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value) { @@ -301,6 +472,7 @@ public void Append(System.TimeSpan value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value, StandardFormat format) { @@ -315,6 +487,22 @@ public void Append(System.TimeSpan value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.TimeSpan value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.TimeSpan value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value) { @@ -329,6 +517,7 @@ public void Append(System.UInt16 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value, StandardFormat format) { @@ -343,6 +532,22 @@ public void Append(System.UInt16 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt16 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt16 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value) { @@ -357,6 +562,7 @@ public void Append(System.UInt32 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value, StandardFormat format) { @@ -371,6 +577,22 @@ public void Append(System.UInt32 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt32 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt32 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value) { @@ -385,6 +607,7 @@ public void Append(System.UInt64 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value, StandardFormat format) { @@ -399,6 +622,22 @@ public void Append(System.UInt64 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt64 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt64 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value) { @@ -413,6 +652,7 @@ public void Append(System.Guid value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value, StandardFormat format) { @@ -427,5 +667,20 @@ public void Append(System.Guid value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Guid value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Guid value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } } } \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta index 3fb02d6f..257e3abd 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b686713f7d79dc24ca68a44e1c0a7b8e +guid: d3c9ebcd92d8b6842821732af2a75fba MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 935f38af..9beee4e3 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -7,7 +7,7 @@ namespace Cysharp.Text { - public partial struct Utf8ValueStringBuilder : IDisposable + public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter { public delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); @@ -43,9 +43,18 @@ static Utf8ValueStringBuilder() byte[] buffer; int index; + /// Length of written buffer. public int Length => index; + + /// Get the written buffer data. public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + /// Get the written buffer data. + public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + + /// Get the written buffer data. + public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf8ValueStringBuilder(bool disposeImmediately) { @@ -67,12 +76,18 @@ public Utf8ValueStringBuilder(bool disposeImmediately) index = 0; } + /// + /// Return the inner buffer to pool. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (buffer.Length != ThreadStaticBufferSize) { - ArrayPool.Shared.Return(buffer); + if (buffer != null) + { + ArrayPool.Shared.Return(buffer); + } } buffer = null; index = 0; @@ -105,8 +120,9 @@ void Grow(int sizeHint = 0) buffer = newBuffer; } + /// Appends the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendNewLine() + public void AppendLine() { if (crlf) { @@ -123,6 +139,7 @@ public void AppendNewLine() } } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void Append(char value) { @@ -138,14 +155,15 @@ public unsafe void Append(char value) } } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(char value) { Append(value); - AppendNewLine(); + AppendLine(); } - + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { @@ -158,13 +176,15 @@ public void Append(string value) index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(string value) { Append(value); - AppendNewLine(); + AppendLine(); } + /// Appends the string representation of a specified value to this instance. public void Append(T value) { if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) @@ -178,14 +198,16 @@ public void Append(T value) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. public void AppendLine(T value) { Append(value); - AppendNewLine(); + AppendLine(); } // Output + /// Copy inner buffer to the destination span. public bool TryCopyTo(Span destination, out int bytesWritten) { if (destination.Length < index) @@ -199,19 +221,33 @@ public bool TryCopyTo(Span destination, out int bytesWritten) return true; } - public Task CopyToAsync(Stream stream) + /// Write inner buffer to stream. + public Task WriteToAsync(Stream stream) { return stream.WriteAsync(buffer, 0, index); } + /// Encode the innner utf8 buffer to a System.String. public override string ToString() { return UTF8NoBom.GetString(buffer, 0, index); } - // IBufferWriter like interface. + // IBufferWriter + + /// IBufferWriter.GetMemory. + public Memory GetMemory(int sizeHint) + { + if ((buffer.Length - index) < sizeHint) + { + Grow(sizeHint); + } + + return buffer.AsMemory(index); + } - public Span GetWritableBuffer(int sizeHint = 0) + /// IBufferWriter.GetSpan. + public Span GetSpan(int sizeHint) { if ((buffer.Length - index) < sizeHint) { @@ -221,6 +257,7 @@ public Span GetWritableBuffer(int sizeHint = 0) return buffer.AsSpan(index); } + /// IBufferWriter.Advance. public void Advance(int count) { index += count; @@ -236,6 +273,9 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + /// + /// Register custom formatter + /// public static void RegisterTryFormat(TryFormat formatMethod) { FormatterCache.TryFormatDelegate = formatMethod; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs index a5535be2..22a4b93f 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs @@ -4,13 +4,25 @@ namespace Cysharp.Text { public static partial class ZString { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + return sb.ToString(); } finally @@ -19,13 +31,38 @@ public static string Concat(T0 arg0) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + return sb.ToString(); } finally @@ -34,13 +71,51 @@ public static string Concat(T0 arg0, T1 arg1) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + return sb.ToString(); } finally @@ -49,13 +124,64 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + return sb.ToString(); } finally @@ -64,13 +190,77 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + return sb.ToString(); } finally @@ -79,13 +269,90 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 ar } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + return sb.ToString(); } finally @@ -94,13 +361,103 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + return sb.ToString(); } finally @@ -109,13 +466,116 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + return sb.ToString(); } finally @@ -124,13 +584,129 @@ public static string Concat(T0 arg0, T1 arg1, T2 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + return sb.ToString(); } finally @@ -139,13 +715,142 @@ public static string Concat(T0 arg0, T1 arg1 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + return sb.ToString(); } finally @@ -154,13 +859,155 @@ public static string Concat(T0 arg0, T1 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + return sb.ToString(); } finally @@ -169,13 +1016,168 @@ public static string Concat(T0 arg0 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + return sb.ToString(); } finally @@ -184,13 +1186,181 @@ public static string Concat(T0 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + return sb.ToString(); } finally @@ -199,13 +1369,194 @@ public static string ConcatConcatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + + if (typeof(T13) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else if (typeof(T13) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else + { + sb.Append(arg13); + } + return sb.ToString(); } finally @@ -214,13 +1565,207 @@ public static string ConcatConcatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + + if (typeof(T13) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else if (typeof(T13) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else + { + sb.Append(arg13); + } + + if (typeof(T14) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else if (typeof(T14) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else + { + sb.Append(arg14); + } + return sb.ToString(); } finally @@ -229,13 +1774,220 @@ public static string ConcatConcatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + + if (typeof(T13) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else if (typeof(T13) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else + { + sb.Append(arg13); + } + + if (typeof(T14) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else if (typeof(T14) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else + { + sb.Append(arg14); + } + + if (typeof(T15) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg15)); + } + else if (typeof(T15) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg15)); + } + else + { + sb.Append(arg15); + } + return sb.ToString(); } finally diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs index 1860dae7..d421e182 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs @@ -4,6 +4,7 @@ namespace Cysharp.Text { public static partial class ZString { + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0) { @@ -19,6 +20,7 @@ public static string Format(string format, T0 arg0) } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1) { @@ -34,6 +36,7 @@ public static string Format(string format, T0 arg0, T1 arg1) } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) { @@ -49,6 +52,7 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2 } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { @@ -64,6 +68,7 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { @@ -79,6 +84,7 @@ public static string Format(string format, T0 arg0, T1 arg1, } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { @@ -94,6 +100,7 @@ public static string Format(string format, T0 arg0, T1 a } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { @@ -109,6 +116,7 @@ public static string Format(string format, T0 arg0, } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { @@ -124,6 +132,7 @@ public static string Format(string format, T0 ar } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { @@ -139,6 +148,7 @@ public static string Format(string format, T } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { @@ -154,6 +164,7 @@ public static string Format(string forma } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { @@ -169,6 +180,7 @@ public static string Format(string } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { @@ -184,6 +196,7 @@ public static string Format(st } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { @@ -199,6 +212,7 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { @@ -214,6 +228,7 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { @@ -229,6 +244,7 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 3108f4a2..5a94d147 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -7,26 +7,31 @@ namespace Cysharp.Text { public static partial class ZString { + /// Create the Utf16 string StringBuilder. public static Utf16ValueStringBuilder CreateStringBuilder() { return new Utf16ValueStringBuilder(false); } + /// Create the Utf16 string StringBuilder, when true uses thread-static buffer that is faster but must return immediately. public static Utf8ValueStringBuilder CreateUtf8StringBuilder() { return new Utf8ValueStringBuilder(false); } + /// Create the Utf8(`Span[byte]`) StringBuilder. public static Utf16ValueStringBuilder CreateStringBuilder(bool notNested) { return new Utf16ValueStringBuilder(notNested); } + /// Create the Utf8(`Span[byte]`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) { return new Utf8ValueStringBuilder(notNested); } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, params T[] values) { var sb = new Utf8ValueStringBuilder(true); @@ -48,6 +53,29 @@ public static string Join(char separator, params T[] values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(char separator, ReadOnlySpan values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, IEnumerable values) { var sb = new Utf8ValueStringBuilder(true); @@ -75,6 +103,7 @@ public static string Join(char separator, IEnumerable values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { var sb = new Utf8ValueStringBuilder(true); @@ -96,6 +125,29 @@ public static string Join(string separator, params T[] values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(string separator, ReadOnlySpan values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, IEnumerable values) { var sb = new Utf8ValueStringBuilder(true); diff --git a/src/ZString.Unity/ProjectSettings/Physics2DSettings.asset b/src/ZString.Unity/ProjectSettings/Physics2DSettings.asset index 71e598122cc35abfe2ba430bdda9b917083f46c4..6c5cf8a004ac48f27cb36f7cdea139eb4d3e812f 100644 GIT binary patch literal 2028 zcmd^A%WmQ@6y5U`?xM2-L;{q@E`VsMO6fFArCA}981U4wk?oYy(fs>dKN3SH@?CL*hctsofI8jXfQg8}*$)Sh-n zMH3ZHVxl$WTQ#g9l&u!)UnJ3YG$m7p;SsgqSrJJwqaP%FAyQGnhp1!Ow-UcWlp*^4 z4$L}&{~Cj4Klo$O3EAMB={eTc9#|X7$ZP^sM|dGjBw#-S0@mOc;`OcRlTg$=RFSqt z3Y+Cl615X79iqSjbNv25Il*!)q=Xu5nyqG7fDzy3>@(_Of#FhOu9!_B-Vm z3I;9ViS^rZ1^NQcaaW-4^;mEX;TD^XBHDQNw)bMa*t-rx{EHJceh|tPnZwMehW6qV zbOBBZ0GunTG~vlH7Sf2O0JGJM!wmPr^$?~<)Dw{qwdkbjYzV6mGgj3Wj9jQ=W@l zeMy^Ao<2e@MCq@y{jpC$^-D>&TLOZ#Ln$MkikgAwcp3}#W>`vBMO{``C7B`((d)?w z!!)2u@zJWRqQWZeUQiANoLpTZK{$G$Q&m6b#o2adt0>nZrWtIUTSO<}?>SroqVA~n zt$~IAgv1&)YR0`9WC@QkV{4qess)ER;&`(P&h>dtM}^IFx6=Eo~7vI^b7RgOG3| z;TI0VP5&nBb?eBiSaVQ*gna_A(`^mv&)Vgj4}RSBqTVC~G&D5K!_p5sK z>ecIy5n|1V5NnSMA=V3VD}IE??cTGme{cV8J172{pP#oZ=x!&NpI<$9`PkOiu9k<- zU5*aCa%}q$v~$-8fv+r22$5jQyzC^Yj?%*C+)9yrY>9+pX_8eJ@}IzOgW?9%6%zDG zNnt^A7PdE`&G{>-6n#=sXucV3^3$zYHb$jai5`Irn#3@l^)?p5m(wd`@xhFxkCGCB6SC8`XNd&TdPB$1Lr^WPM|TarXd3e8vG!l3<)k|a`6Xue)?UMJX&loXopRQw)E z5-BM(A5xsx(Q@-$#qTxnQ;PQ)`1^|AXW(Bbe!qeLsQ4BGzpD6F1K)rf2jlmEf#(!| zu!mbRKSsfEL}HudUBUcg{v20)dl$);=556vGVnJQf7rl3Q2Y@C|6K7M2L7$$JHeOU zzv%z3iuW7%pNj7?@O20-Y&_4fnv-jS313}jlEpJ&0V zYW`lREpbLswo^W)_@f41SNt&pKdSiSJ=_xX?-)4!!*g!g^|gO|&is>q`wU$B_mqKa z|MvIr)IVSOcc6zaj^EP;uH(mhJ@akkIavM=@u;#?E>$f5?_2Qw>KIz6CF)KQvT8+a4YS4%sJE3cPxxs@NHRw#( zZ7!IyOo?NFk?KsNBSP(B#4cP6emL0}Utzml(3@#|@?vyh+ zQJI>y8?lDe)q|SnIMW!Kx+8n_z{8&W1}!Lmdh{wprNED2a&%%Ma$=!^ITVbKPRo$w z7_x3xv?FH(fpueq!fxVBsDX{hjbg`dbZSA!lftBmkGM_;>6Q^zC#pIjECC&HX4JA> zT`BN9w@FiUC!_Zer|izgZJgG^nuIj&`t6_{ z_29DWH;-T?CyIMqcy79hzok%$#v9ZX14vORCy zZk&ileFWMbmnk~t$P~cwMYsqShG4i{4sn;cKM{mev{CeC>`qjh43Goz$ff0MUng`{ zr^5~dS#_~EFhIZ3Ln($~Fr(wEtrutP6G$sB2t_DbVqDmALb`M@;>D9vnn|?_$H7Tm zH5b!EhwToJTWuQmnb4h;cQ$!{%iiRUXFHjj-~Y}3egwX}vgu;hOa6hyyBzw!F&{KX4}e767T`Sb88p${lYe(s}PXtST{UQLpNeIR^T|C{A+@lq#i diff --git a/src/ZString.Unity/ZString.Unity.unitypackage b/src/ZString.Unity/ZString.Unity.unitypackage new file mode 100644 index 0000000000000000000000000000000000000000..d6fd0d4e823d44567e06e52d773e667039fc38c7 GIT binary patch literal 183356 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%0AT0a%?Iz+p#d!clt!4Q_yak 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 the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0) { var copyFrom = 0; @@ -91,12 +92,7 @@ public void AppendFormat(string format, T0 arg0) } } - public void AppendFormatLine(string format, T0 arg0) - { - AppendFormat(format, arg0); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1) { var copyFrom = 0; @@ -197,12 +193,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1) - { - AppendFormat(format, arg0, arg1); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { var copyFrom = 0; @@ -316,12 +307,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2) - { - AppendFormat(format, arg0, arg1, arg2); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; @@ -448,12 +434,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - AppendFormat(format, arg0, arg1, arg2, arg3); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; @@ -593,12 +574,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; @@ -751,12 +727,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; @@ -922,12 +893,7 @@ public void AppendFormat(string format, T0 arg0, T1 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; @@ -1106,12 +1072,7 @@ public void AppendFormat(string format, T0 arg0, } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; @@ -1303,12 +1264,7 @@ public void AppendFormat(string format, T0 a } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; @@ -1513,12 +1469,7 @@ public void AppendFormat(string format, } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; @@ -1736,12 +1687,7 @@ public void AppendFormat(string for } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; @@ -1972,12 +1918,7 @@ public void AppendFormat(strin } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; @@ -2221,12 +2162,7 @@ public void AppendFormat( } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; @@ -2483,12 +2419,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; @@ -2758,12 +2689,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; @@ -3046,11 +2972,5 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - } } \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt index 1e760313..901e030f 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt @@ -15,11 +15,6 @@ return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); } - - static string CreateParameterNames(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); - } #> using System; @@ -28,6 +23,7 @@ namespace Cysharp.Text public partial struct Utf16ValueStringBuilder { <# for(var i = 1; i <= 16; i++) { #> + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { var copyFrom = 0; @@ -117,12 +113,6 @@ namespace Cysharp.Text } } - public void AppendFormatLine<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) - { - AppendFormat(format, <#= CreateParameterNames(i) #>); - AppendNewLine(); - } - <# } #> } } \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs deleted file mode 100644 index 78c1169b..00000000 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.cs +++ /dev/null @@ -1,5609 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { - public void Concat(T0 arg0) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0) - { - Concat(arg0); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1) - { - Concat(arg0, arg1); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2) - { - Concat(arg0, arg1, arg2); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - Concat(arg0, arg1, arg2, arg3); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - Concat(arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - if (typeof(T12) == typeof(string)) - { - var s12 = Unsafe.As(ref arg12); - if (s12 != null) - { - TryGrow(s12.Length); - s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s12.Length; - } - } - else if (typeof(T12) == typeof(int)) - { - int written = 0; - - var i12 = Unsafe.As(ref arg12); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - if (typeof(T12) == typeof(string)) - { - var s12 = Unsafe.As(ref arg12); - if (s12 != null) - { - TryGrow(s12.Length); - s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s12.Length; - } - } - else if (typeof(T12) == typeof(int)) - { - int written = 0; - - var i12 = Unsafe.As(ref arg12); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - - if (typeof(T13) == typeof(string)) - { - var s13 = Unsafe.As(ref arg13); - if (s13 != null) - { - TryGrow(s13.Length); - s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s13.Length; - } - } - else if (typeof(T13) == typeof(int)) - { - int written = 0; - - var i13 = Unsafe.As(ref arg13); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - if (typeof(T12) == typeof(string)) - { - var s12 = Unsafe.As(ref arg12); - if (s12 != null) - { - TryGrow(s12.Length); - s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s12.Length; - } - } - else if (typeof(T12) == typeof(int)) - { - int written = 0; - - var i12 = Unsafe.As(ref arg12); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - - if (typeof(T13) == typeof(string)) - { - var s13 = Unsafe.As(ref arg13); - if (s13 != null) - { - TryGrow(s13.Length); - s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s13.Length; - } - } - else if (typeof(T13) == typeof(int)) - { - int written = 0; - - var i13 = Unsafe.As(ref arg13); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - - if (typeof(T14) == typeof(string)) - { - var s14 = Unsafe.As(ref arg14); - if (s14 != null) - { - TryGrow(s14.Length); - s14.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s14.Length; - } - } - else if (typeof(T14) == typeof(int)) - { - int written = 0; - - var i14 = Unsafe.As(ref arg14); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - if (typeof(T0) == typeof(string)) - { - var s0 = Unsafe.As(ref arg0); - if (s0 != null) - { - TryGrow(s0.Length); - s0.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s0.Length; - } - } - else if (typeof(T0) == typeof(int)) - { - int written = 0; - - var i0 = Unsafe.As(ref arg0); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i0)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - } - - if (typeof(T1) == typeof(string)) - { - var s1 = Unsafe.As(ref arg1); - if (s1 != null) - { - TryGrow(s1.Length); - s1.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s1.Length; - } - } - else if (typeof(T1) == typeof(int)) - { - int written = 0; - - var i1 = Unsafe.As(ref arg1); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i1)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - } - - if (typeof(T2) == typeof(string)) - { - var s2 = Unsafe.As(ref arg2); - if (s2 != null) - { - TryGrow(s2.Length); - s2.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s2.Length; - } - } - else if (typeof(T2) == typeof(int)) - { - int written = 0; - - var i2 = Unsafe.As(ref arg2); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i2)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - } - - if (typeof(T3) == typeof(string)) - { - var s3 = Unsafe.As(ref arg3); - if (s3 != null) - { - TryGrow(s3.Length); - s3.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s3.Length; - } - } - else if (typeof(T3) == typeof(int)) - { - int written = 0; - - var i3 = Unsafe.As(ref arg3); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i3)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - } - - if (typeof(T4) == typeof(string)) - { - var s4 = Unsafe.As(ref arg4); - if (s4 != null) - { - TryGrow(s4.Length); - s4.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s4.Length; - } - } - else if (typeof(T4) == typeof(int)) - { - int written = 0; - - var i4 = Unsafe.As(ref arg4); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i4)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - } - - if (typeof(T5) == typeof(string)) - { - var s5 = Unsafe.As(ref arg5); - if (s5 != null) - { - TryGrow(s5.Length); - s5.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s5.Length; - } - } - else if (typeof(T5) == typeof(int)) - { - int written = 0; - - var i5 = Unsafe.As(ref arg5); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i5)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - } - - if (typeof(T6) == typeof(string)) - { - var s6 = Unsafe.As(ref arg6); - if (s6 != null) - { - TryGrow(s6.Length); - s6.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s6.Length; - } - } - else if (typeof(T6) == typeof(int)) - { - int written = 0; - - var i6 = Unsafe.As(ref arg6); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i6)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - } - - if (typeof(T7) == typeof(string)) - { - var s7 = Unsafe.As(ref arg7); - if (s7 != null) - { - TryGrow(s7.Length); - s7.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s7.Length; - } - } - else if (typeof(T7) == typeof(int)) - { - int written = 0; - - var i7 = Unsafe.As(ref arg7); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i7)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - } - - if (typeof(T8) == typeof(string)) - { - var s8 = Unsafe.As(ref arg8); - if (s8 != null) - { - TryGrow(s8.Length); - s8.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s8.Length; - } - } - else if (typeof(T8) == typeof(int)) - { - int written = 0; - - var i8 = Unsafe.As(ref arg8); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i8)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - } - - if (typeof(T9) == typeof(string)) - { - var s9 = Unsafe.As(ref arg9); - if (s9 != null) - { - TryGrow(s9.Length); - s9.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s9.Length; - } - } - else if (typeof(T9) == typeof(int)) - { - int written = 0; - - var i9 = Unsafe.As(ref arg9); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i9)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - } - - if (typeof(T10) == typeof(string)) - { - var s10 = Unsafe.As(ref arg10); - if (s10 != null) - { - TryGrow(s10.Length); - s10.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s10.Length; - } - } - else if (typeof(T10) == typeof(int)) - { - int written = 0; - - var i10 = Unsafe.As(ref arg10); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i10)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - } - - if (typeof(T11) == typeof(string)) - { - var s11 = Unsafe.As(ref arg11); - if (s11 != null) - { - TryGrow(s11.Length); - s11.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s11.Length; - } - } - else if (typeof(T11) == typeof(int)) - { - int written = 0; - - var i11 = Unsafe.As(ref arg11); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i11)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - } - - if (typeof(T12) == typeof(string)) - { - var s12 = Unsafe.As(ref arg12); - if (s12 != null) - { - TryGrow(s12.Length); - s12.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s12.Length; - } - } - else if (typeof(T12) == typeof(int)) - { - int written = 0; - - var i12 = Unsafe.As(ref arg12); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i12)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - } - - if (typeof(T13) == typeof(string)) - { - var s13 = Unsafe.As(ref arg13); - if (s13 != null) - { - TryGrow(s13.Length); - s13.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s13.Length; - } - } - else if (typeof(T13) == typeof(int)) - { - int written = 0; - - var i13 = Unsafe.As(ref arg13); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i13)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - } - - if (typeof(T14) == typeof(string)) - { - var s14 = Unsafe.As(ref arg14); - if (s14 != null) - { - TryGrow(s14.Length); - s14.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s14.Length; - } - } - else if (typeof(T14) == typeof(int)) - { - int written = 0; - - var i14 = Unsafe.As(ref arg14); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i14)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - } - - if (typeof(T15) == typeof(string)) - { - var s15 = Unsafe.As(ref arg15); - if (s15 != null) - { - TryGrow(s15.Length); - s15.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s15.Length; - } - } - else if (typeof(T15) == typeof(int)) - { - int written = 0; - - var i15 = Unsafe.As(ref arg15); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i15)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i15)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - } - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - - } -} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.tt deleted file mode 100644 index b0563c34..00000000 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.Concat.tt +++ /dev/null @@ -1,86 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); - } - - - static string CreateParameterNames(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); - } -#> -using System; -using System.Runtime.CompilerServices; - -namespace Cysharp.Text -{ - public partial struct Utf16ValueStringBuilder - { -<# for(var i = 1; i <= 16; i++) { #> - public void Concat<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) - { -<# for(var j = 0; j < i; j++) { #> - if (typeof(T<#= j #>) == typeof(string)) - { - var s<#= j #> = Unsafe.As, string>(ref arg<#= j #>); - if (s<#= j #> != null) - { - TryGrow(s<#= j #>.Length); - s<#= j #>.AsSpan().TryCopyTo(buffer.AsSpan(index)); - index += s<#= j#>.Length; - } - } - else if (typeof(T<#= j #>) == typeof(int)) - { - int written = 0; - - var i<#= j #> = Unsafe.As, int>(ref arg<#= j #>); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i<#= j #>)) - { - Grow(); - if (!FastNumberWriter.TryWriteInt64(buffer.AsSpan(index), out written, (long)i<#= j #>)) - { - ThrowArgumentException(nameof(arg<#= j #>)); - } - } - index += written; - } - else - { - int written = 0; - - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) - { - Grow(written); - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, default)) - { - ThrowArgumentException(nameof(arg<#= j #>)); - } - } - index += written; - } - -<# } #> - } - - public void ConcatLine<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) - { - Concat(<#= CreateParameterNames(i) #>); - AppendNewLine(); - } - -<# } #> - } -} \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index 06d14d57..29a6d10c 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -5,6 +5,7 @@ namespace Cysharp.Text { public partial struct Utf16ValueStringBuilder { + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) { @@ -19,6 +20,7 @@ public void Append(System.Byte value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value, string format) { @@ -33,6 +35,22 @@ public void Append(System.Byte value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Byte value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Byte value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value) { @@ -47,6 +65,7 @@ public void Append(System.DateTime value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value, string format) { @@ -61,6 +80,22 @@ public void Append(System.DateTime value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTime value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTime value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value) { @@ -75,6 +110,7 @@ public void Append(System.DateTimeOffset value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value, string format) { @@ -89,6 +125,22 @@ public void Append(System.DateTimeOffset value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTimeOffset value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTimeOffset value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value) { @@ -103,6 +155,7 @@ public void Append(System.Decimal value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value, string format) { @@ -117,6 +170,22 @@ public void Append(System.Decimal value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Decimal value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Decimal value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value) { @@ -131,6 +200,7 @@ public void Append(System.Double value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value, string format) { @@ -145,6 +215,22 @@ public void Append(System.Double value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Double value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Double value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value) { @@ -159,6 +245,7 @@ public void Append(System.Int16 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value, string format) { @@ -173,6 +260,22 @@ public void Append(System.Int16 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int16 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int16 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value) { @@ -187,6 +290,7 @@ public void Append(System.Int32 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value, string format) { @@ -201,6 +305,22 @@ public void Append(System.Int32 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int32 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int32 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value) { @@ -215,6 +335,7 @@ public void Append(System.Int64 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value, string format) { @@ -229,6 +350,22 @@ public void Append(System.Int64 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int64 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int64 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value) { @@ -243,6 +380,7 @@ public void Append(System.SByte value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value, string format) { @@ -257,6 +395,22 @@ public void Append(System.SByte value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.SByte value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.SByte value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value) { @@ -271,6 +425,7 @@ public void Append(System.Single value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value, string format) { @@ -285,6 +440,22 @@ public void Append(System.Single value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Single value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Single value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value) { @@ -299,6 +470,7 @@ public void Append(System.TimeSpan value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value, string format) { @@ -313,6 +485,22 @@ public void Append(System.TimeSpan value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.TimeSpan value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.TimeSpan value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value) { @@ -327,6 +515,7 @@ public void Append(System.UInt16 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value, string format) { @@ -341,6 +530,22 @@ public void Append(System.UInt16 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt16 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt16 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value) { @@ -355,6 +560,7 @@ public void Append(System.UInt32 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value, string format) { @@ -369,6 +575,22 @@ public void Append(System.UInt32 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt32 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt32 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value) { @@ -383,6 +605,7 @@ public void Append(System.UInt64 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value, string format) { @@ -397,6 +620,22 @@ public void Append(System.UInt64 value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt64 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt64 value, string format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value) { @@ -411,6 +650,7 @@ public void Append(System.Guid value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value, string format) { @@ -425,5 +665,20 @@ public void Append(System.Guid value, string format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Guid value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Guid value, string format) + { + Append(value, format); + AppendLine(); + } } } \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt index 47477c05..545619e6 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt @@ -33,6 +33,7 @@ namespace Cysharp.Text public partial struct Utf16ValueStringBuilder { <# foreach(var t in spanFormattables) { #> + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(<#= t.FullName #> value) { @@ -47,6 +48,7 @@ namespace Cysharp.Text index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(<#= t.FullName #> value, string format) { @@ -61,6 +63,21 @@ namespace Cysharp.Text index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(<#= t.FullName #> value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(<#= t.FullName #> value, string format) + { + Append(value, format); + AppendLine(); + } <# } #> } } \ No newline at end of file diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index f77ad572..e20d28cb 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -39,9 +39,13 @@ static Utf16ValueStringBuilder() char[] buffer; int index; + /// Length of written buffer. public int Length => index; + /// Get the written buffer data. public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + /// Get the written buffer data. public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + /// Get the written buffer data. public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -65,12 +69,18 @@ public Utf16ValueStringBuilder(bool disposeImmediately) index = 0; } + /// + /// Return the inner buffer to pool. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (buffer.Length != ThreadStaticBufferSize) { - ArrayPool.Shared.Return(buffer); + if (buffer != null) + { + ArrayPool.Shared.Return(buffer); + } } buffer = null; index = 0; @@ -103,8 +113,9 @@ void Grow(int sizeHint = 0) buffer = newBuffer; } + /// Appends the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendNewLine() + public void AppendLine() { if (crlf) { @@ -121,6 +132,7 @@ public void AppendNewLine() } } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(char value) { @@ -132,13 +144,15 @@ public void Append(char value) buffer[index++] = value; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(char value) { Append(value); - AppendNewLine(); + AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { @@ -151,13 +165,15 @@ public void Append(string value) index += value.Length; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(string value) { Append(value); - AppendNewLine(); + AppendLine(); } + /// Appends the string representation of a specified value to this instance. public void Append(T value) { if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) @@ -171,14 +187,16 @@ public void Append(T value) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. public void AppendLine(T value) { Append(value); - AppendNewLine(); + AppendLine(); } // Output + /// Copy inner buffer to the destination span. public bool TryCopyTo(Span destination, out int charsWritten) { if (destination.Length < index) @@ -192,6 +210,7 @@ public bool TryCopyTo(Span destination, out int charsWritten) return true; } + /// Converts the value of this instance to a System.String. public override string ToString() { return new string(buffer, 0, index); @@ -199,6 +218,7 @@ public override string ToString() // IBufferWriter + /// IBufferWriter.GetMemory. public Memory GetMemory(int sizeHint) { if ((buffer.Length - index) < sizeHint) @@ -209,6 +229,7 @@ public Memory GetMemory(int sizeHint) return buffer.AsMemory(index); } + /// IBufferWriter.GetSpan. public Span GetSpan(int sizeHint) { if ((buffer.Length - index) < sizeHint) @@ -219,6 +240,7 @@ public Span GetSpan(int sizeHint) return buffer.AsSpan(index); } + /// IBufferWriter.Advance. public void Advance(int count) { index += count; @@ -234,6 +256,9 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + /// + /// Register custom formatter + /// public static void RegisterTryFormat(TryFormat formatMethod) { FormatterCache.TryFormatDelegate = formatMethod; diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index 2060e11c..b68e7d61 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -5,6 +5,7 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder { + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0) { var copyFrom = 0; @@ -88,12 +89,7 @@ public void AppendFormat(string format, T0 arg0) } } - public void AppendFormatLine(string format, T0 arg0) - { - AppendFormat(format, arg0); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1) { var copyFrom = 0; @@ -190,12 +186,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1) - { - AppendFormat(format, arg0, arg1); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { var copyFrom = 0; @@ -305,12 +296,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2) - { - AppendFormat(format, arg0, arg1, arg2); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; @@ -433,12 +419,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - AppendFormat(format, arg0, arg1, arg2, arg3); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; @@ -574,12 +555,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; @@ -728,12 +704,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; @@ -895,12 +866,7 @@ public void AppendFormat(string format, T0 arg0, T1 } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; @@ -1075,12 +1041,7 @@ public void AppendFormat(string format, T0 arg0, } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; @@ -1268,12 +1229,7 @@ public void AppendFormat(string format, T0 a } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; @@ -1474,12 +1430,7 @@ public void AppendFormat(string format, } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; @@ -1693,12 +1644,7 @@ public void AppendFormat(string for } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; @@ -1925,12 +1871,7 @@ public void AppendFormat(strin } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; @@ -2170,12 +2111,7 @@ public void AppendFormat( } } - public void AppendFormatLine(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; @@ -2428,12 +2364,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; @@ -2699,12 +2630,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; @@ -2983,11 +2909,5 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - } } \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt index d288f8c1..a831264b 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt @@ -29,6 +29,7 @@ namespace Cysharp.Text public partial struct Utf8ValueStringBuilder { <# for(var i = 1; i <= 16; i++) { #> + /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { var copyFrom = 0; @@ -114,12 +115,6 @@ namespace Cysharp.Text } } - public void AppendFormatLine<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) - { - AppendFormat(format, <#= CreateParameterNames(i) #>); - AppendNewLine(); - } - <# } #> } } \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs deleted file mode 100644 index 4ee6f9c9..00000000 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.cs +++ /dev/null @@ -1,1576 +0,0 @@ -using System; - -namespace Cysharp.Text -{ - public partial struct Utf8ValueStringBuilder - { - public void Concat(T0 arg0) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0) - { - Concat(arg0); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1) - { - Concat(arg0, arg1); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2) - { - Concat(arg0, arg1, arg2); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3) - { - Concat(arg0, arg1, arg2, arg3); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - Concat(arg0, arg1, arg2, arg3, arg4); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); - AppendNewLine(); - } - - public void Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - int written; - var span = buffer.AsSpan(); - - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - - if (!FormatterCache.TryFormatDelegate(arg15, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - - } - - public void ConcatLine(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) - { - Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); - AppendNewLine(); - } - - } -} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.tt deleted file mode 100644 index 6c314d20..00000000 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.Concat.tt +++ /dev/null @@ -1,58 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); - } - - - static string CreateParameterNames(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); - } -#> -using System; - -namespace Cysharp.Text -{ - public partial struct Utf8ValueStringBuilder - { -<# for(var i = 1; i <= 16; i++) { #> - public void Concat<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) - { - int written; - var span = buffer.AsSpan(); - -<# for(var j = 0; j < i; j++) { #> - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, span.Slice(index), out written, default)) - { - Grow(written); - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, span.Slice(index), out written, default)) - { - ThrowArgumentException(nameof(arg<#= j #>)); - } - } - index += written; - -<# } #> - } - - public void ConcatLine<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) - { - Concat(<#= CreateParameterNames(i) #>); - AppendNewLine(); - } - -<# } #> - } -} \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index bcf2135c..ecfef55d 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -7,6 +7,7 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder { + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) { @@ -21,6 +22,7 @@ public void Append(System.Byte value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value, StandardFormat format) { @@ -35,6 +37,22 @@ public void Append(System.Byte value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Byte value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Byte value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value) { @@ -49,6 +67,7 @@ public void Append(System.DateTime value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value, StandardFormat format) { @@ -63,6 +82,22 @@ public void Append(System.DateTime value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTime value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTime value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value) { @@ -77,6 +112,7 @@ public void Append(System.DateTimeOffset value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value, StandardFormat format) { @@ -91,6 +127,22 @@ public void Append(System.DateTimeOffset value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTimeOffset value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.DateTimeOffset value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value) { @@ -105,6 +157,7 @@ public void Append(System.Decimal value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value, StandardFormat format) { @@ -119,6 +172,22 @@ public void Append(System.Decimal value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Decimal value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Decimal value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value) { @@ -133,6 +202,7 @@ public void Append(System.Double value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value, StandardFormat format) { @@ -147,6 +217,22 @@ public void Append(System.Double value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Double value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Double value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value) { @@ -161,6 +247,7 @@ public void Append(System.Int16 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value, StandardFormat format) { @@ -175,6 +262,22 @@ public void Append(System.Int16 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int16 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int16 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value) { @@ -189,6 +292,7 @@ public void Append(System.Int32 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value, StandardFormat format) { @@ -203,6 +307,22 @@ public void Append(System.Int32 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int32 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int32 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value) { @@ -217,6 +337,7 @@ public void Append(System.Int64 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value, StandardFormat format) { @@ -231,6 +352,22 @@ public void Append(System.Int64 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int64 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Int64 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value) { @@ -245,6 +382,7 @@ public void Append(System.SByte value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value, StandardFormat format) { @@ -259,6 +397,22 @@ public void Append(System.SByte value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.SByte value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.SByte value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value) { @@ -273,6 +427,7 @@ public void Append(System.Single value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value, StandardFormat format) { @@ -287,6 +442,22 @@ public void Append(System.Single value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Single value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Single value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value) { @@ -301,6 +472,7 @@ public void Append(System.TimeSpan value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value, StandardFormat format) { @@ -315,6 +487,22 @@ public void Append(System.TimeSpan value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.TimeSpan value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.TimeSpan value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value) { @@ -329,6 +517,7 @@ public void Append(System.UInt16 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value, StandardFormat format) { @@ -343,6 +532,22 @@ public void Append(System.UInt16 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt16 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt16 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value) { @@ -357,6 +562,7 @@ public void Append(System.UInt32 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value, StandardFormat format) { @@ -371,6 +577,22 @@ public void Append(System.UInt32 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt32 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt32 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value) { @@ -385,6 +607,7 @@ public void Append(System.UInt64 value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value, StandardFormat format) { @@ -399,6 +622,22 @@ public void Append(System.UInt64 value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt64 value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.UInt64 value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value) { @@ -413,6 +652,7 @@ public void Append(System.Guid value) index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value, StandardFormat format) { @@ -427,5 +667,20 @@ public void Append(System.Guid value, StandardFormat format) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Guid value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Guid value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } } } \ No newline at end of file diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt index 86330736..c84b7980 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt @@ -35,6 +35,7 @@ namespace Cysharp.Text public partial struct Utf8ValueStringBuilder { <# foreach(var t in spanFormattables) { #> + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(<#= t.FullName #> value) { @@ -49,6 +50,7 @@ namespace Cysharp.Text index += written; } + /// Appends the string representation of a specified value to this instance with numeric format strings. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(<#= t.FullName #> value, StandardFormat format) { @@ -63,6 +65,21 @@ namespace Cysharp.Text index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(<#= t.FullName #> value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(<#= t.FullName #> value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } <# } #> } } \ No newline at end of file diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 3bd8f443..9beee4e3 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -43,9 +43,16 @@ static Utf8ValueStringBuilder() byte[] buffer; int index; + /// Length of written buffer. public int Length => index; + + /// Get the written buffer data. public ReadOnlySpan AsSpan() => buffer.AsSpan(0, index); + + /// Get the written buffer data. public ReadOnlyMemory AsMemory() => buffer.AsMemory(0, index); + + /// Get the written buffer data. public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -69,12 +76,18 @@ public Utf8ValueStringBuilder(bool disposeImmediately) index = 0; } + /// + /// Return the inner buffer to pool. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { if (buffer.Length != ThreadStaticBufferSize) { - ArrayPool.Shared.Return(buffer); + if (buffer != null) + { + ArrayPool.Shared.Return(buffer); + } } buffer = null; index = 0; @@ -107,8 +120,9 @@ void Grow(int sizeHint = 0) buffer = newBuffer; } + /// Appends the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendNewLine() + public void AppendLine() { if (crlf) { @@ -125,6 +139,7 @@ public void AppendNewLine() } } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe void Append(char value) { @@ -140,14 +155,15 @@ public unsafe void Append(char value) } } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(char value) { Append(value); - AppendNewLine(); + AppendLine(); } - + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { @@ -160,13 +176,15 @@ public void Append(string value) index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(string value) { Append(value); - AppendNewLine(); + AppendLine(); } + /// Appends the string representation of a specified value to this instance. public void Append(T value) { if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) @@ -180,14 +198,16 @@ public void Append(T value) index += written; } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. public void AppendLine(T value) { Append(value); - AppendNewLine(); + AppendLine(); } // Output + /// Copy inner buffer to the destination span. public bool TryCopyTo(Span destination, out int bytesWritten) { if (destination.Length < index) @@ -201,11 +221,13 @@ public bool TryCopyTo(Span destination, out int bytesWritten) return true; } - public Task CopyToAsync(Stream stream) + /// Write inner buffer to stream. + public Task WriteToAsync(Stream stream) { return stream.WriteAsync(buffer, 0, index); } + /// Encode the innner utf8 buffer to a System.String. public override string ToString() { return UTF8NoBom.GetString(buffer, 0, index); @@ -213,6 +235,7 @@ public override string ToString() // IBufferWriter + /// IBufferWriter.GetMemory. public Memory GetMemory(int sizeHint) { if ((buffer.Length - index) < sizeHint) @@ -223,6 +246,7 @@ public Memory GetMemory(int sizeHint) return buffer.AsMemory(index); } + /// IBufferWriter.GetSpan. public Span GetSpan(int sizeHint) { if ((buffer.Length - index) < sizeHint) @@ -233,6 +257,7 @@ public Span GetSpan(int sizeHint) return buffer.AsSpan(index); } + /// IBufferWriter.Advance. public void Advance(int count) { index += count; @@ -248,6 +273,9 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + /// + /// Register custom formatter + /// public static void RegisterTryFormat(TryFormat formatMethod) { FormatterCache.TryFormatDelegate = formatMethod; diff --git a/src/ZString/ZString.Concat.cs b/src/ZString/ZString.Concat.cs index a5535be2..22a4b93f 100644 --- a/src/ZString/ZString.Concat.cs +++ b/src/ZString/ZString.Concat.cs @@ -4,13 +4,25 @@ namespace Cysharp.Text { public static partial class ZString { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + return sb.ToString(); } finally @@ -19,13 +31,38 @@ public static string Concat(T0 arg0) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + return sb.ToString(); } finally @@ -34,13 +71,51 @@ public static string Concat(T0 arg0, T1 arg1) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + return sb.ToString(); } finally @@ -49,13 +124,64 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + return sb.ToString(); } finally @@ -64,13 +190,77 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + return sb.ToString(); } finally @@ -79,13 +269,90 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 ar } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + return sb.ToString(); } finally @@ -94,13 +361,103 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + return sb.ToString(); } finally @@ -109,13 +466,116 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + return sb.ToString(); } finally @@ -124,13 +584,129 @@ public static string Concat(T0 arg0, T1 arg1, T2 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + return sb.ToString(); } finally @@ -139,13 +715,142 @@ public static string Concat(T0 arg0, T1 arg1 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + return sb.ToString(); } finally @@ -154,13 +859,155 @@ public static string Concat(T0 arg0, T1 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + return sb.ToString(); } finally @@ -169,13 +1016,168 @@ public static string Concat(T0 arg0 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + return sb.ToString(); } finally @@ -184,13 +1186,181 @@ public static string Concat(T0 } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + return sb.ToString(); } finally @@ -199,13 +1369,194 @@ public static string ConcatConcatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + + if (typeof(T13) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else if (typeof(T13) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else + { + sb.Append(arg13); + } + return sb.ToString(); } finally @@ -214,13 +1565,207 @@ public static string ConcatConcatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + + if (typeof(T13) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else if (typeof(T13) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else + { + sb.Append(arg13); + } + + if (typeof(T14) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else if (typeof(T14) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else + { + sb.Append(arg14); + } + return sb.ToString(); } finally @@ -229,13 +1774,220 @@ public static string ConcatConcatenates the string representation of some specified objects. public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + if (typeof(T0) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else if (typeof(T0) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg0)); + } + else + { + sb.Append(arg0); + } + + if (typeof(T1) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else if (typeof(T1) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg1)); + } + else + { + sb.Append(arg1); + } + + if (typeof(T2) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else if (typeof(T2) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg2)); + } + else + { + sb.Append(arg2); + } + + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + + if (typeof(T13) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else if (typeof(T13) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else + { + sb.Append(arg13); + } + + if (typeof(T14) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else if (typeof(T14) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else + { + sb.Append(arg14); + } + + if (typeof(T15) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg15)); + } + else if (typeof(T15) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg15)); + } + else + { + sb.Append(arg15); + } + return sb.ToString(); } finally diff --git a/src/ZString/ZString.Concat.tt b/src/ZString/ZString.Concat.tt index a669a454..5eb68bfc 100644 --- a/src/ZString/ZString.Concat.tt +++ b/src/ZString/ZString.Concat.tt @@ -15,11 +15,6 @@ return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); } - - static string CreateParameterNames(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); - } #> using System.Runtime.CompilerServices; @@ -28,13 +23,27 @@ namespace Cysharp.Text public static partial class ZString { <# for(var i = 1; i <= 16; i++) { #> - [MethodImpl(MethodImplOptions.AggressiveInlining)] + /// Concatenates the string representation of some specified objects. public static string Concat<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) { var sb = new Utf16ValueStringBuilder(true); try { - sb.Concat(<#= CreateParameterNames(i) #>); +<# for(var j = 0; j < i; j++) { #> + if (typeof(T<#= j #>) == typeof(string)) + { + sb.Append(Unsafe.As, string>(ref arg<#= j #>)); + } + else if (typeof(T<#= j #>) == typeof(int)) + { + sb.Append(Unsafe.As, int>(ref arg<#= j #>)); + } + else + { + sb.Append(arg<#= j #>); + } + +<# } #> return sb.ToString(); } finally diff --git a/src/ZString/ZString.Format.cs b/src/ZString/ZString.Format.cs index 1860dae7..d421e182 100644 --- a/src/ZString/ZString.Format.cs +++ b/src/ZString/ZString.Format.cs @@ -4,6 +4,7 @@ namespace Cysharp.Text { public static partial class ZString { + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0) { @@ -19,6 +20,7 @@ public static string Format(string format, T0 arg0) } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1) { @@ -34,6 +36,7 @@ public static string Format(string format, T0 arg0, T1 arg1) } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) { @@ -49,6 +52,7 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2 } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) { @@ -64,6 +68,7 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { @@ -79,6 +84,7 @@ public static string Format(string format, T0 arg0, T1 arg1, } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { @@ -94,6 +100,7 @@ public static string Format(string format, T0 arg0, T1 a } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { @@ -109,6 +116,7 @@ public static string Format(string format, T0 arg0, } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { @@ -124,6 +132,7 @@ public static string Format(string format, T0 ar } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { @@ -139,6 +148,7 @@ public static string Format(string format, T } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { @@ -154,6 +164,7 @@ public static string Format(string forma } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { @@ -169,6 +180,7 @@ public static string Format(string } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { @@ -184,6 +196,7 @@ public static string Format(st } } + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { @@ -199,6 +212,7 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { @@ -214,6 +228,7 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { @@ -229,6 +244,7 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { diff --git a/src/ZString/ZString.Format.tt b/src/ZString/ZString.Format.tt index c0e32e88..67287387 100644 --- a/src/ZString/ZString.Format.tt +++ b/src/ZString/ZString.Format.tt @@ -28,6 +28,7 @@ namespace Cysharp.Text public static partial class ZString { <# for(var i = 1; i <= 16; i++) { #> + /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index d7a46c66..5a94d147 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -7,26 +7,31 @@ namespace Cysharp.Text { public static partial class ZString { + /// Create the Utf16 string StringBuilder. public static Utf16ValueStringBuilder CreateStringBuilder() { return new Utf16ValueStringBuilder(false); } + /// Create the Utf16 string StringBuilder, when true uses thread-static buffer that is faster but must return immediately. public static Utf8ValueStringBuilder CreateUtf8StringBuilder() { return new Utf8ValueStringBuilder(false); } + /// Create the Utf8(`Span[byte]`) StringBuilder. public static Utf16ValueStringBuilder CreateStringBuilder(bool notNested) { return new Utf16ValueStringBuilder(notNested); } + /// Create the Utf8(`Span[byte]`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) { return new Utf8ValueStringBuilder(notNested); } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, params T[] values) { var sb = new Utf8ValueStringBuilder(true); @@ -48,6 +53,7 @@ public static string Join(char separator, params T[] values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { var sb = new Utf8ValueStringBuilder(true); @@ -69,6 +75,7 @@ public static string Join(char separator, ReadOnlySpan values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, IEnumerable values) { var sb = new Utf8ValueStringBuilder(true); @@ -96,6 +103,7 @@ public static string Join(char separator, IEnumerable values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { var sb = new Utf8ValueStringBuilder(true); @@ -117,6 +125,7 @@ public static string Join(string separator, params T[] values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, ReadOnlySpan values) { var sb = new Utf8ValueStringBuilder(true); @@ -138,6 +147,7 @@ public static string Join(string separator, ReadOnlySpan values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, IEnumerable values) { var sb = new Utf8ValueStringBuilder(true); diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 8d42f575..6180befa 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -4,6 +4,9 @@ netstandard2.1;netstandard2.0 Cysharp.Text true + true + 1701;1702;1591 + $(Version) Cysharp @@ -36,10 +39,6 @@ Utf16ValueStringBuilder.AppendMany.cs TextTemplatingFileGenerator - - TextTemplatingFileGenerator - Utf16ValueStringBuilder.Concat.cs - Utf16ValueStringBuilder.CreateFormatter.cs TextTemplatingFileGenerator @@ -56,10 +55,6 @@ Utf8ValueStringBuilder.AppendMany.cs TextTemplatingFileGenerator - - TextTemplatingFileGenerator - Utf8ValueStringBuilder.Concat.cs - Utf8ValueStringBuilder.CreateFormatter.cs TextTemplatingFileGenerator @@ -93,11 +88,6 @@ True True - - True - True - Utf16ValueStringBuilder.Concat.tt - Utf16ValueStringBuilder.CreateFormatter.tt True @@ -118,11 +108,6 @@ True Utf8ValueStringBuilder.AppendMany.tt - - True - True - Utf8ValueStringBuilder.Concat.tt - True True diff --git a/tests/ZString.Tests/Primitives.cs b/tests/ZString.Tests/Primitives.cs index f9e1914b..1a2ed264 100644 --- a/tests/ZString.Tests/Primitives.cs +++ b/tests/ZString.Tests/Primitives.cs @@ -38,8 +38,8 @@ public void Integer(int x, int y) var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.Concat(x, y); - sb4.Concat(x, y); + sb3.Append(x); sb3.Append(y); + sb4.Append(x); sb4.Append(y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); @@ -74,8 +74,8 @@ public void UInt64(ulong x, ulong y) var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.Concat(x, y); - sb4.Concat(x, y); + sb3.Append(x); sb3.Append(y); + sb4.Append(x); sb4.Append(y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); @@ -110,8 +110,8 @@ public void Double(double x, double y) var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.Concat(x, y); - sb4.Concat(x, y); + sb3.Append(x); sb3.Append(y); + sb4.Append(x); sb4.Append(y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); @@ -143,8 +143,8 @@ public void Single(float x, float y) var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.Concat(x, y); - sb4.Concat(x, y); + sb3.Append(x); sb3.Append(y); + sb4.Append(x); sb4.Append(y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); @@ -170,7 +170,7 @@ public void Others() var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb1.Append(z); sb1.Append(g); //sb2.Append(x, StandardFormat.Parse("O")); sb2.Append(y, StandardFormat.Parse("O")); sb2.Append(z); sb2.Append(g); - sb3.Concat(x, y, z, g); + sb3.Append(x); sb3.Append(y); sb3.Append(z); sb3.Append(g); //sb4.Concat(x, y, z, g); sb5.Append(x); sb5.Append(y); sb5.Append(z); sb5.Append(g); @@ -195,8 +195,8 @@ public void EnumTest() var sb5 = new StringBuilder(); sb1.Append(x); sb1.Append(y); sb2.Append(x); sb2.Append(y); - sb3.Concat(x, y); - sb4.Concat(x, y); + sb3.Append(x); sb3.Append(y); + sb4.Append(x); sb4.Append(y); sb5.Append(x); sb5.Append(y); sb1.ToString().Should().Be(sb2.ToString()); From f687b8b0553b9256c190b348fa31d85aa07963a0 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Fri, 14 Feb 2020 05:16:33 +0900 Subject: [PATCH 025/139] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7bcd1bf5..bb31afc3 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ZString * Struct StringBuilder to avoid allocation of builder itself * Rent write buffer from `ThreadStatic` or `ArrayPool` * All append methods are generics(`Append(T value)`) and write to buffer directly instead of concatenate `value.ToString` -* `T0`~`T15` AppendFormat(`AppendFormat(string format, T0 arg0, ..., T15 arg15)` avoids boxing of stuct argument +* `T0`~`T15` AppendFormat(`AppendFormat(string format, T0 arg0, ..., T15 arg15)` avoids boxing of struct argument * Also `T0`~`T15` Concat(`Concat(T0 arg0, ..., T15 arg15)`) avoid boxing and `value.ToString` allocation * Convinient `ZString.Format/Concat/Join` methods can replace instead of `String.Format/Concat/Join` * Can use inner buffer to avoid allocate final string @@ -213,4 +213,4 @@ License --- This library is licensed under the the MIT License. -.NET Standard 2.0 and Unity version borrows [dotnet/runtime](https://github.com/dotnet/runtime) conversion methods, there exists under `ZString/Number` directory. \ No newline at end of file +.NET Standard 2.0 and Unity version borrows [dotnet/runtime](https://github.com/dotnet/runtime) conversion methods, there exists under `ZString/Number` directory. From 13d66458b42c3d22ef2d76c4aee703f1a1f9a83b Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Fri, 14 Feb 2020 05:19:13 +0900 Subject: [PATCH 026/139] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bb31afc3..42894bb2 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,9 @@ ZString * `T0`~`T15` AppendFormat(`AppendFormat(string format, T0 arg0, ..., T15 arg15)` avoids boxing of struct argument * Also `T0`~`T15` Concat(`Concat(T0 arg0, ..., T15 arg15)`) avoid boxing and `value.ToString` allocation * Convinient `ZString.Format/Concat/Join` methods can replace instead of `String.Format/Concat/Join` -* Can use inner buffer to avoid allocate final string * Can build both Utf16(`Span`) and Utf8(`Span`) directly +* Can use inner buffer to avoid allocate final string +* Integrated with Unity TextMeshPro to avoid string allocation ![image](https://user-images.githubusercontent.com/46207/74473217-9061e200-4ee6-11ea-9a77-14d740886faa.png) @@ -26,7 +27,7 @@ This graph compares following codes. `"x:" + x + " y:" + y + " z:" + z` is converted to `String.Concat(new []{ "x:", x.ToString(), " y:", y.ToString(), " z:", z.ToString() })` by C# compiler. It has each `.ToString` allocation and params array allocation. `string.Format` calls `String.Format(string, object, object, object)` so each arguments causes int -> object boxing. -All `ZString` methods only allocate final string. Also, `ZString` has enabled to access inner buffer so if output target has stringless api, you can achieve completely zero allocation. +All `ZString` methods only allocate final string. Also, `ZString` has enabled to access inner buffer so if output target has stringless api(like Unity TextMeshPro's `SetCharArray`), you can achieve completely zero allocation. Getting Started --- From 34259d825d31cdc9639245892ca4dd889fe1df96 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Fri, 14 Feb 2020 05:21:09 +0900 Subject: [PATCH 027/139] Update ZString.csproj --- src/ZString/ZString.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 6180befa..ece257ca 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -13,7 +13,7 @@ Cysharp © Cysharp, Inc. string; - Zero alloction StringBuilder for .NET Core and Unity. + Zero allocation StringBuilder for .NET Core and Unity. https://github.com/Cysharp/ZString $(PackageProjectUrl) git From 1a4f1447a75d2a2460e19c7b976e148fa27943a3 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Sat, 15 Feb 2020 23:15:34 +0900 Subject: [PATCH 028/139] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42894bb2..518e0d50 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Reference | CreateStringBuilder(bool notNested) | Utf16ValueStringBuilder | Create the Utf16 string StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | | CreateUtf8StringBuilder() | Utf8ValueStringBuilder | Create the Utf8(`Span`) StringBuilder. | | CreateUtf8StringBuilder(bool notNested) | Utf8ValueStringBuilder | Create the Utf8(`Span`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | -| `Join(char|string, T[]/IE)` | string | Concatenates the elements of an array, using the specified seperator between each element. | +| `Join(char/string, T[]/IE)` | string | Concatenates the elements of an array, using the specified seperator between each element. | | `Concat(T0,..,T15)` | string | Concatenates the string representation of some specified values. | | `Format(string, T0,..,T15)` | string | Replaces one or more format items in a string with the string representation of some specified values. | From 49dc0908b0bc3c64e98a9f5c7d557f2bd3bfa86e Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Mon, 17 Feb 2020 21:40:35 +0900 Subject: [PATCH 029/139] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 518e0d50..0d4eae97 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ For .NET Core, use NuGet. For Unity, check the [releases](https://github.com/Cysharp/ZString/releases) page, download `ZString.Unity.unitypackage`. ```csharp +using Cysharp.Text; // namespace + async void Example(int x, int y, int z) { // same as x + y + z From e245eb4ec1916b71e66da6e736f7bc8d3e5cc03c Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Thu, 20 Feb 2020 12:10:45 +0900 Subject: [PATCH 030/139] Update README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 0d4eae97..5e0ef973 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,18 @@ Reference | SetText(Utf16ValueStringBuilder) | void | Set inner buffer to text mesh pro directly to avoid string allocation. | | `SetTextFormat(string, T0,..,T15)` | void | Set formatted string without string allocation. | +Unity +--- +In Unity, if you encount the following error + +``` +The type 'Unsafe' exists in both 'System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' +``` + +This is caused from dll conflict, for example `Unity Collections` package includes `System.Runtime.CompilerServices.Unsafe.dll` but ZString provides `System.Runtime.CompilerServices.Unsafe.dll` to `Plugins`. + +To resolve this issue, please remove `Plugins/System.Runtime.CompilerServices.Unsafe.dll` that included in ZString. + Advanced Tips --- `ZString.CreateStringBuilder(notNested:true)` is a special optimized parameter that uses `ThreadStatic` buffer instead of rent from `ArrayPool`. It is slightly faster but can not use in nested. From 1d9de35e05143bb54707ae74f958fe3fd45676ce Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Thu, 20 Feb 2020 15:02:24 +0900 Subject: [PATCH 031/139] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e0ef973..8bef39d0 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ The type 'Unsafe' exists in both 'System.Runtime.CompilerServices.Unsafe, Versio This is caused from dll conflict, for example `Unity Collections` package includes `System.Runtime.CompilerServices.Unsafe.dll` but ZString provides `System.Runtime.CompilerServices.Unsafe.dll` to `Plugins`. -To resolve this issue, please remove `Plugins/System.Runtime.CompilerServices.Unsafe.dll` that included in ZString. +To resolve this issue, please remove `System.Runtime.CompilerServices.Unsafe.dll` in `Unity Collections` that exists at `\Library\PackageCache\`. Advanced Tips --- From 59573afaccb7a9e8d1f116c2f9db09e4bb445198 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Thu, 20 Feb 2020 15:18:27 +0900 Subject: [PATCH 032/139] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bef39d0..2bc3b39d 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,11 @@ The type 'Unsafe' exists in both 'System.Runtime.CompilerServices.Unsafe, Versio This is caused from dll conflict, for example `Unity Collections` package includes `System.Runtime.CompilerServices.Unsafe.dll` but ZString provides `System.Runtime.CompilerServices.Unsafe.dll` to `Plugins`. -To resolve this issue, please remove `System.Runtime.CompilerServices.Unsafe.dll` in `Unity Collections` that exists at `\Library\PackageCache\`. +Detail of issue in Unity Forum - [[Bug 1214643][2019.3.0f5] System.Runtime.CompilerServices.Unsafe clashes with imported dll](https://forum.unity.com/threads/bug-1214643-2019-3-0f5-system-runtime-compilerservices-unsafe-clashes-with-imported-dll.816426/) + +Workround: +- Copy Collections from Library/PackageCache to %Project Folder%/Packages +- Remove CompilerServices.Unsafe dll from said folder Advanced Tips --- From 9556ad685ddab2baa9c025d7a0f4762f637ae158 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Wed, 26 Feb 2020 16:20:32 +0900 Subject: [PATCH 033/139] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2bc3b39d..fb4049ad 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ This graph compares following codes. All `ZString` methods only allocate final string. Also, `ZString` has enabled to access inner buffer so if output target has stringless api(like Unity TextMeshPro's `SetCharArray`), you can achieve completely zero allocation. +The blog post of detailed explanation by author: [medium@neuecc/ZString](https://medium.com/@neuecc/zstring-zero-allocation-stringbuilder-for-net-core-and-unity-f3163c88c887) + Getting Started --- For .NET Core, use NuGet. From f1cde72479e12fba9ed10cd579f510aac56ee423 Mon Sep 17 00:00:00 2001 From: Lukasz Pyrzyk Date: Thu, 27 Feb 2020 21:50:03 +0100 Subject: [PATCH 034/139] Bumped libs --- sandbox/ConsoleApp/ConsoleApp.csproj | 2 +- tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj | 4 ++-- tests/ZString.Tests/ZString.Tests.csproj | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sandbox/ConsoleApp/ConsoleApp.csproj b/sandbox/ConsoleApp/ConsoleApp.csproj index db193179..9e6b29f0 100644 --- a/sandbox/ConsoleApp/ConsoleApp.csproj +++ b/sandbox/ConsoleApp/ConsoleApp.csproj @@ -7,7 +7,7 @@ - + diff --git a/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj b/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj index ae89ff5a..ec484dbe 100644 --- a/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj +++ b/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj @@ -7,8 +7,8 @@
- - + + diff --git a/tests/ZString.Tests/ZString.Tests.csproj b/tests/ZString.Tests/ZString.Tests.csproj index fc5eef7f..e9eec7d5 100644 --- a/tests/ZString.Tests/ZString.Tests.csproj +++ b/tests/ZString.Tests/ZString.Tests.csproj @@ -7,8 +7,8 @@
- - + + all From a95e2dd6c7d45fcf147935e0a06d784a65e58912 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Mon, 2 Mar 2020 10:32:31 +0900 Subject: [PATCH 035/139] WIP, prepared format --- src/ZString/PreparedFormat.cs | 183 ++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/ZString/PreparedFormat.cs diff --git a/src/ZString/PreparedFormat.cs b/src/ZString/PreparedFormat.cs new file mode 100644 index 00000000..2948f92b --- /dev/null +++ b/src/ZString/PreparedFormat.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; + +namespace Cysharp.Text +{ + public sealed partial class PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public PreparedFormat(string format) + { + this.FormatString = format; + this.segments = Parse(format); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + // TODO:test 2args. + public string Format(T0 arg0, T1 arg1) + { + // using (var sb = new Utf16ValueStringBuilder(true)) + + + { + while (true) + { + var buffer = sb.AsArraySegment().Array; + if (TryFormat(buffer, arg0, arg1, out var written)) + { + return new string(buffer, 0, written); + } + else + { + // sb.ad + } + } + } + } + + public bool TryFormat(Span span, T0 arg0, T1 arg1, out int written) + { + written = 0; + + if (span.Length < MinSize) + { + return false; + } + + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + span = span.Slice(item.Count); + written += item.Count; + } + else + { + switch (item.FormatIndex) + { + case 0: + { + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg0, span, out var argWritten, item.FormatString.AsSpan())) + { + written += argWritten; + return false; + } + span = span.Slice(written); + written += argWritten; + break; + } + case 1: + { + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + written += argWritten; + return false; + } + span = span.Slice(written); + written += argWritten; + break; + } + default: + break; + } + } + } + + return true; + } + + FormatSegment[] Parse(string format) + { + var list = new List(); + + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + list.Add(new FormatSegment(copyFrom, size, false, 0, null)); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + list.Add(new FormatSegment(copyFrom, size, false, 0, null)); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + list.Add(new FormatSegment(0, 0, true, indexParse.Index, indexParse.FormatString.ToString())); + + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + list.Add(new FormatSegment(copyFrom, size, false, 0, null)); + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + } + + { + // final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + list.Add(new FormatSegment(copyFrom, copyLength, false, 0, null)); + } + } + + return list.ToArray(); + } + + readonly struct FormatSegment + { + public readonly int Offset; + public readonly int Count; + public readonly bool IsFormatArgument; + public readonly int FormatIndex; + public readonly string FormatString; + + public FormatSegment(int offset, int count, bool isFormatArgument, int formatIndex, string formatString) + { + Offset = offset; + Count = count; + IsFormatArgument = isFormatArgument; + FormatIndex = formatIndex; + FormatString = formatString; + } + } + } +} From d0d2146367fa9f3fe03cd3229135569ddf96403a Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 30 Mar 2020 23:45:30 +0900 Subject: [PATCH 036/139] many improv --- README.md | 69 +- .../Assets/Scripts/ZString/PreparedFormat.cs | 6071 +++++++++++++++++ .../Utf16ValueStringBuilder.AppendFormat.cs | 614 +- .../ZString/Utf16ValueStringBuilder.cs | 4 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 612 +- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 6 +- .../Assets/Scripts/ZString/ZString.Concat.cs | 426 +- .../Assets/Scripts/ZString/ZString.Format.cs | 64 +- .../Assets/Scripts/ZString/ZString.Prepare.cs | 168 + .../Scripts/ZString/ZString.Utf8Format.cs | 3234 +++++++++ .../Assets/Scripts/ZString/ZString.cs | 49 +- src/ZString/ExceptionUtil.cs | 19 + src/ZString/PreparedFormat.cs | 6058 +++++++++++++++- src/ZString/PreparedFormat.tt | 119 + src/ZString/PreparedFormatHelper.cs | 109 + .../Utf16ValueStringBuilder.AppendFormat.cs | 614 +- .../Utf16ValueStringBuilder.AppendFormat.tt | 10 +- src/ZString/Utf16ValueStringBuilder.cs | 4 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 612 +- .../Utf8ValueStringBuilder.AppendFormat.tt | 16 +- src/ZString/Utf8ValueStringBuilder.cs | 14 +- src/ZString/ZString.Concat.cs | 426 +- src/ZString/ZString.Concat.tt | 14 +- src/ZString/ZString.Format.cs | 64 +- src/ZString/ZString.Format.tt | 6 +- src/ZString/ZString.Prepare.cs | 200 + src/ZString/ZString.Prepare.tt | 34 + src/ZString/ZString.Utf8Format.cs | 3250 +++++++++ src/ZString/ZString.Utf8Format.tt | 122 + src/ZString/ZString.cs | 49 +- src/ZString/ZString.csproj | 43 + tests/ZString.Tests/FormatTest.cs | 26 + tests/ZString.Tests/JoinTest.cs | 29 + 33 files changed, 21307 insertions(+), 1848 deletions(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs create mode 100644 src/ZString/ExceptionUtil.cs create mode 100644 src/ZString/PreparedFormat.tt create mode 100644 src/ZString/PreparedFormatHelper.cs create mode 100644 src/ZString/ZString.Prepare.cs create mode 100644 src/ZString/ZString.Prepare.tt create mode 100644 src/ZString/ZString.Utf8Format.cs create mode 100644 src/ZString/ZString.Utf8Format.tt diff --git a/README.md b/README.md index fb4049ad..13e84964 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ ZString * Struct StringBuilder to avoid allocation of builder itself * Rent write buffer from `ThreadStatic` or `ArrayPool` * All append methods are generics(`Append(T value)`) and write to buffer directly instead of concatenate `value.ToString` -* `T0`~`T15` AppendFormat(`AppendFormat(string format, T0 arg0, ..., T15 arg15)` avoids boxing of struct argument -* Also `T0`~`T15` Concat(`Concat(T0 arg0, ..., T15 arg15)`) avoid boxing and `value.ToString` allocation +* `T1`~`T16` AppendFormat(`AppendFormat(string format, T1 arg1, ..., T16 arg16)` avoids boxing of struct argument +* Also `T1`~`T16` Concat(`Concat(T1 arg1, ..., T16 arg16)`) avoid boxing and `value.ToString` allocation * Convinient `ZString.Format/Concat/Join` methods can replace instead of `String.Format/Concat/Join` * Can build both Utf16(`Span`) and Utf8(`Span`) directly * Can use inner buffer to avoid allocate final string @@ -72,6 +72,10 @@ async void Example(int x, int y, int z) sb.TryCopyTo(dest, out var written); } + // prepare format, return value should store to field(like RegexOptions.Compile) + var prepared = ZString.PrepareUtf16("x:{0}, y:{1:000}"); + _ = prepared.Format(10, 20); + // C# 8.0, Using declarations // create Utf8 StringBuilder that build Utf8 directly to avoid encoding using var sb2 = ZString.CreateUtf8StringBuilder(); @@ -80,6 +84,7 @@ async void Example(int x, int y, int z) // directly write to steam or dest to avoid allocation await sb2.WriteToAsync(stream); + sb2.CopyTo(bufferWritter); sb2.TryCopyTo(dest, out var written); } ``` @@ -95,8 +100,11 @@ Reference | CreateUtf8StringBuilder() | Utf8ValueStringBuilder | Create the Utf8(`Span`) StringBuilder. | | CreateUtf8StringBuilder(bool notNested) | Utf8ValueStringBuilder | Create the Utf8(`Span`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. | | `Join(char/string, T[]/IE)` | string | Concatenates the elements of an array, using the specified seperator between each element. | -| `Concat(T0,..,T15)` | string | Concatenates the string representation of some specified values. | -| `Format(string, T0,..,T15)` | string | Replaces one or more format items in a string with the string representation of some specified values. | +| `PrepareUtf16(string)` | `Utf16PreparedFormat` | Prepare string format to avoid parse template in each operation. | +| `PrepareUtf8(string)` | `Utf8PreparedFormat` | Prepare string format to avoid parse template in each operation. | +| `Concat(T1,..,T16)` | string | Concatenates the string representation of some specified values. | +| `Format(string, T1,..,T16)` | string | Replaces one or more format items in a string with the string representation of some specified values. | +| `Utf8Format(IBufferWriter, T1,..,T16)` | void | Replaces one or more format items in a string with the string representation of some specified values. | **struct Utf16ValueStringBuilder : `IBufferWriter`, IDisposable** @@ -112,7 +120,7 @@ Reference | `AppendLine()` | void | Appends the default line terminator to the end of this instance. | | `AppendLine(T value)` | void | Appends the string representation of a specified value followed by the default line terminator to the end of this instance. | | `AppendLine(T value, string format)` | void | Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. | -| `AppendFormat(string, T0,..,T15)` | void | Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. | +| `AppendFormat(string, T1,..,T16)` | void | Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. | | `TryCopyTo(Span, out int)` | bool | Copy inner buffer to the destination span. | | ToString() | string | Converts the value of this instance to a System.String. | | GetMemory(int sizeHint) | `Memory` | IBufferWriter.GetMemory. | @@ -134,7 +142,8 @@ Reference | `AppendLine()` | void | Appends the default line terminator to the end of this instance. | | `AppendLine(T value)` | void | Appends the string representation of a specified value followed by the default line terminator to the end of this instance. | | `AppendLine(T value, StandardFormat format)` | void | Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. | -| `AppendFormat(string, T0,..,T15)` | void | Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. | +| `AppendFormat(string, T1,..,T16)` | void | Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. | +| `CopyTo(IBufferWriter)` | void | Copy inner buffer to the buffer writer. | | `TryCopyTo(Span, out int)` | bool | Copy inner buffer to the destination span. | | WriteToAsync(Stream stream) | Task | Write inner buffer to stream. | | ToString() | string | Encode the innner utf8 buffer to a System.String. | @@ -143,12 +152,26 @@ Reference | Advance(int count) | void | IBufferWriter.Advance. | | static `RegisterTryFormat(TryFormat)` | void | Register custom formatter. | +**class `Utf16PreparedFormat`** + +| method | returns | description | +| -- | -- | -- | +| `Format` | string | Replaces one or more format items in a string with the string representation of some specified values. | +| `FormatTo(ref TBufferWriter, T1,..,T16)` | void | Replaces one or more format items in a string with the string representation of some specified values. | + +**class `Utf8PreparedFormat`** + +| method | returns | description | +| -- | -- | -- | +| `Format` | string | Replaces one or more format items in a string with the string representation of some specified values. | +| `FormatTo(ref TBufferWriter, T1,..,T16)` | void | Replaces one or more format items in a string with the string representation of some specified values. | + **static class TextMeshProExtensions**(Unity only) | method | returns | description | | -- | -- | -- | | SetText(Utf16ValueStringBuilder) | void | Set inner buffer to text mesh pro directly to avoid string allocation. | -| `SetTextFormat(string, T0,..,T15)` | void | Set formatted string without string allocation. | +| `SetTextFormat(string, T1,..,T16)` | void | Set formatted string without string allocation. | Unity --- @@ -218,6 +241,38 @@ Utf8ValueStringBuilder.RegisterTryFormat((MyStruct value, Span destination --- +`Utf16ValueStringBuilder` and `Utf8ValueStringBuilder` are mutable struct, be careful to copy by passing method. Use `ref` and `try-finally`. + +```csharp +void Build() +{ + var sb = ZString.CreateStringBuilder(); + try + { + BuildHeader(ref sb); + BuildMessage(ref sb); + } + finally + { + // when use with `ref`, can not use `using`. + sb.Dispose(); + } +} + + +void BuildHeader(ref Utf16ValueStringBuilder builder) +{ + //.. +} + +void BuildMessage(ref Utf16ValueStringBuilder builder) +{ + //.. +} +``` + +--- + `Utf8ValueStringBuilder` and `Utf16ValueStringBuilder` implements `IBufferWriter` so you can pass serializer(such as `JsonSerializer` of `System.Text.Json`). But be careful to boxing copy, `ValueStringBuilder` is mutable struct. For example, ```csharp diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs new file mode 100644 index 00000000..4759b589 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs @@ -0,0 +1,6071 @@ +using System; +using System.Text; +using System.Buffers; + +namespace Cysharp.Text +{ + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + case 14: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + case 14: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + sb.Advance(argWritten); + break; + } + case 15: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg16)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + case 14: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + case 14: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + sb.Advance(argWritten); + break; + } + case 15: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg16)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 6eae9735..95caf7b4 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -5,7 +5,7 @@ namespace Cysharp.Text public partial struct Utf16ValueStringBuilder { /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0) + public void AppendFormat(string format, T1 arg1) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -17,7 +17,7 @@ public void AppendFormat(string format, T0 arg0) { throw new FormatException("invalid format"); } - + if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; @@ -44,12 +44,12 @@ public void AppendFormat(string format, T0 arg0) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -93,7 +93,7 @@ public void AppendFormat(string format, T0 arg0) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1) + public void AppendFormat(string format, T1 arg1, T2 arg2) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -132,12 +132,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -145,12 +145,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -194,7 +194,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -233,12 +233,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -246,12 +246,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -259,12 +259,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -308,7 +308,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -347,12 +347,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -360,12 +360,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -373,12 +373,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -386,12 +386,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg3)); + ThrowArgumentException(nameof(arg4)); } } index += written; @@ -435,7 +435,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -474,12 +474,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -487,12 +487,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -500,12 +500,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -513,12 +513,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg3)); + ThrowArgumentException(nameof(arg4)); } } index += written; @@ -526,12 +526,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg4)); + ThrowArgumentException(nameof(arg5)); } } index += written; @@ -575,7 +575,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -613,19 +613,6 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -638,7 +625,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -651,7 +638,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -664,7 +651,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -677,7 +664,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -690,6 +677,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -728,7 +728,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -766,19 +766,6 @@ public void AppendFormat(string format, T0 arg0, T1 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -791,7 +778,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -804,7 +791,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -817,7 +804,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -830,7 +817,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -843,7 +830,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -856,6 +843,19 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -894,7 +894,7 @@ public void AppendFormat(string format, T0 arg0, T1 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -932,19 +932,6 @@ public void AppendFormat(string format, T0 arg0, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -957,7 +944,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -970,7 +957,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -983,7 +970,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -996,7 +983,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1009,7 +996,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1022,7 +1009,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1035,6 +1022,19 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1073,7 +1073,7 @@ public void AppendFormat(string format, T0 arg0, } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1111,19 +1111,6 @@ public void AppendFormat(string format, T0 a switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1136,7 +1123,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1149,7 +1136,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1162,7 +1149,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1175,7 +1162,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1188,7 +1175,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1201,7 +1188,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1214,7 +1201,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1227,6 +1214,19 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1265,7 +1265,7 @@ public void AppendFormat(string format, T0 a } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1303,19 +1303,6 @@ public void AppendFormat(string format, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1328,7 +1315,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1341,7 +1328,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1354,7 +1341,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1367,7 +1354,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1380,7 +1367,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1393,7 +1380,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1406,7 +1393,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1419,7 +1406,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1432,6 +1419,19 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1470,7 +1470,7 @@ public void AppendFormat(string format, } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1509,12 +1509,12 @@ public void AppendFormat(string for { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -1522,20 +1522,7 @@ public void AppendFormat(string for } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } - case 2: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) @@ -1546,7 +1533,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1559,7 +1546,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1572,7 +1559,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1585,7 +1572,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1598,7 +1585,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1611,7 +1598,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1624,7 +1611,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1637,7 +1624,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1650,6 +1637,19 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1688,7 +1688,7 @@ public void AppendFormat(string for } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1726,19 +1726,6 @@ public void AppendFormat(strin switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1751,7 +1738,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1764,7 +1751,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1777,7 +1764,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1790,7 +1777,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1803,7 +1790,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1816,7 +1803,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1829,7 +1816,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1842,7 +1829,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1855,7 +1842,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1868,7 +1855,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 11: + case 10: { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1881,6 +1868,19 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1919,7 +1919,7 @@ public void AppendFormat(strin } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1957,19 +1957,6 @@ public void AppendFormat( switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1982,7 +1969,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1995,7 +1982,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2008,7 +1995,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2021,7 +2008,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2034,7 +2021,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2047,7 +2034,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2060,7 +2047,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2073,7 +2060,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2086,7 +2073,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2099,7 +2086,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 11: + case 10: { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2112,7 +2099,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 12: + case 11: { if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2125,6 +2112,19 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2163,7 +2163,7 @@ public void AppendFormat( } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2201,19 +2201,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2226,7 +2213,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2239,7 +2226,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2252,7 +2239,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2265,7 +2252,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2278,7 +2265,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2291,7 +2278,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2304,7 +2291,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2317,7 +2304,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2330,7 +2317,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2343,7 +2330,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2356,7 +2343,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2369,7 +2356,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2382,6 +2369,19 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2420,7 +2420,7 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2458,19 +2458,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2483,7 +2470,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2496,7 +2483,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2509,7 +2496,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2522,7 +2509,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2535,7 +2522,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2548,7 +2535,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2561,7 +2548,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2574,7 +2561,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2587,7 +2574,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2600,7 +2587,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2613,7 +2600,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2626,7 +2613,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2639,7 +2626,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2652,6 +2639,19 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2690,7 +2690,7 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2728,19 +2728,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2753,7 +2740,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2766,7 +2753,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2779,7 +2766,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2792,7 +2779,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2805,7 +2792,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2818,7 +2805,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2831,7 +2818,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2844,7 +2831,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2857,7 +2844,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2870,7 +2857,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2883,7 +2870,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2896,7 +2883,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2909,7 +2896,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2922,7 +2909,7 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2935,6 +2922,19 @@ public void AppendFormat.TryFormatDelegate(arg16, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg16)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index e20d28cb..954e2f17 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -86,7 +86,7 @@ public void Dispose() index = 0; } - void TryGrow(int sizeHint) + public void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) { @@ -94,7 +94,7 @@ void TryGrow(int sizeHint) } } - void Grow(int sizeHint = 0) + public void Grow(int sizeHint = 0) { var nextSize = buffer.Length * 2; if (sizeHint != 0) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index b68e7d61..dd60d0c8 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -6,7 +6,7 @@ namespace Cysharp.Text public partial struct Utf8ValueStringBuilder { /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0) + public void AppendFormat(string format, T1 arg1) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -44,12 +44,12 @@ public void AppendFormat(string format, T0 arg0) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -90,7 +90,7 @@ public void AppendFormat(string format, T0 arg0) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1) + public void AppendFormat(string format, T1 arg1, T2 arg2) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -128,12 +128,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -141,12 +141,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -187,7 +187,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -225,12 +225,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -238,12 +238,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -251,12 +251,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -297,7 +297,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -335,12 +335,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -348,12 +348,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -361,12 +361,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -374,12 +374,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg3)); + ThrowArgumentException(nameof(arg4)); } } index += written; @@ -420,7 +420,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -458,12 +458,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -471,12 +471,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -484,12 +484,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -497,12 +497,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg3)); + ThrowArgumentException(nameof(arg4)); } } index += written; @@ -510,12 +510,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg4)); + ThrowArgumentException(nameof(arg5)); } } index += written; @@ -556,7 +556,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -593,19 +593,6 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -618,7 +605,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -631,7 +618,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -644,7 +631,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -657,7 +644,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -670,6 +657,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -705,7 +705,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -742,19 +742,6 @@ public void AppendFormat(string format, T0 arg0, T1 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -767,7 +754,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -780,7 +767,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -793,7 +780,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -806,7 +793,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -819,7 +806,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -832,6 +819,19 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -867,7 +867,7 @@ public void AppendFormat(string format, T0 arg0, T1 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -904,19 +904,6 @@ public void AppendFormat(string format, T0 arg0, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -929,7 +916,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -942,7 +929,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -955,7 +942,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -968,7 +955,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -981,7 +968,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -994,7 +981,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1007,6 +994,19 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1042,7 +1042,7 @@ public void AppendFormat(string format, T0 arg0, } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1079,19 +1079,6 @@ public void AppendFormat(string format, T0 a switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1104,7 +1091,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1117,7 +1104,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1130,7 +1117,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1143,7 +1130,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1156,7 +1143,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1169,7 +1156,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1182,7 +1169,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1195,6 +1182,19 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1230,7 +1230,7 @@ public void AppendFormat(string format, T0 a } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1267,19 +1267,6 @@ public void AppendFormat(string format, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1292,7 +1279,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1305,7 +1292,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1318,7 +1305,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1331,7 +1318,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1344,7 +1331,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1357,7 +1344,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1370,7 +1357,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1383,7 +1370,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1396,6 +1383,19 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1431,7 +1431,7 @@ public void AppendFormat(string format, } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1469,12 +1469,12 @@ public void AppendFormat(string for { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -1482,20 +1482,7 @@ public void AppendFormat(string for } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } - case 2: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) @@ -1506,7 +1493,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1519,7 +1506,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1532,7 +1519,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1545,7 +1532,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1558,7 +1545,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1571,7 +1558,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1584,7 +1571,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1597,7 +1584,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1610,6 +1597,19 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1645,7 +1645,7 @@ public void AppendFormat(string for } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1682,19 +1682,6 @@ public void AppendFormat(strin switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1707,7 +1694,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1720,7 +1707,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1733,7 +1720,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1746,7 +1733,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1759,7 +1746,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1772,7 +1759,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1785,7 +1772,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1798,7 +1785,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1811,7 +1798,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1824,7 +1811,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 11: + case 10: { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1837,6 +1824,19 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1872,7 +1872,7 @@ public void AppendFormat(strin } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1909,19 +1909,6 @@ public void AppendFormat( switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1934,7 +1921,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1947,7 +1934,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1960,7 +1947,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1973,7 +1960,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1986,7 +1973,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1999,7 +1986,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2012,7 +1999,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2025,7 +2012,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2038,7 +2025,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2051,7 +2038,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 11: + case 10: { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2064,7 +2051,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 12: + case 11: { if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2077,6 +2064,19 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2112,7 +2112,7 @@ public void AppendFormat( } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2149,19 +2149,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2174,7 +2161,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2187,7 +2174,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2200,7 +2187,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2213,7 +2200,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2226,7 +2213,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2239,7 +2226,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2252,7 +2239,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2265,7 +2252,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2278,7 +2265,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2291,7 +2278,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2304,7 +2291,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2317,7 +2304,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2330,6 +2317,19 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2365,7 +2365,7 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2402,19 +2402,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2427,7 +2414,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2440,7 +2427,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2453,7 +2440,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2466,7 +2453,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2479,7 +2466,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2492,7 +2479,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2505,7 +2492,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2518,7 +2505,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2531,7 +2518,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2544,7 +2531,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2557,7 +2544,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2570,7 +2557,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2583,7 +2570,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2596,6 +2583,19 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2631,7 +2631,7 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2668,19 +2668,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2693,7 +2680,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2706,7 +2693,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2719,7 +2706,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2732,7 +2719,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2745,7 +2732,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2758,7 +2745,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2771,7 +2758,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2784,7 +2771,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2797,7 +2784,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2810,7 +2797,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2823,7 +2810,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2836,7 +2823,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2849,7 +2836,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2862,7 +2849,7 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2875,6 +2862,19 @@ public void AppendFormat.TryFormatDelegate(arg16, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg16)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 9beee4e3..12a18b65 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -93,7 +93,7 @@ public void Dispose() index = 0; } - void TryGrow(int sizeHint) + public void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) { @@ -101,7 +101,7 @@ void TryGrow(int sizeHint) } } - void Grow(int sizeHint = 0) + public void Grow(int sizeHint = 0) { var nextSize = buffer.Length * 2; if (sizeHint != 0) @@ -281,7 +281,7 @@ public static void RegisterTryFormat(TryFormat formatMethod) FormatterCache.TryFormatDelegate = formatMethod; } - static class FormatterCache + public static class FormatterCache { public static TryFormat TryFormatDelegate; static FormatterCache() diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs index 22a4b93f..4c20ec55 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs @@ -5,22 +5,22 @@ namespace Cysharp.Text public static partial class ZString { /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0) + public static string Concat(T1 arg1) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) + if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg0)); + sb.Append(Unsafe.As(ref arg1)); } - else if (typeof(T0) == typeof(int)) + else if (typeof(T1) == typeof(int)) { - sb.Append(Unsafe.As(ref arg0)); + sb.Append(Unsafe.As(ref arg1)); } else { - sb.Append(arg0); + sb.Append(arg1); } return sb.ToString(); @@ -32,35 +32,35 @@ public static string Concat(T0 arg0) } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1) + public static string Concat(T1 arg1, T2 arg2) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) + if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg0)); + sb.Append(Unsafe.As(ref arg1)); } - else if (typeof(T0) == typeof(int)) + else if (typeof(T1) == typeof(int)) { - sb.Append(Unsafe.As(ref arg0)); + sb.Append(Unsafe.As(ref arg1)); } else { - sb.Append(arg0); + sb.Append(arg1); } - if (typeof(T1) == typeof(string)) + if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + sb.Append(Unsafe.As(ref arg2)); } - else if (typeof(T1) == typeof(int)) + else if (typeof(T2) == typeof(int)) { - sb.Append(Unsafe.As(ref arg1)); + sb.Append(Unsafe.As(ref arg2)); } else { - sb.Append(arg1); + sb.Append(arg2); } return sb.ToString(); @@ -72,24 +72,11 @@ public static string Concat(T0 arg0, T1 arg1) } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2) + public static string Concat(T1 arg1, T2 arg2, T3 arg3) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -116,6 +103,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2) sb.Append(arg2); } + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + return sb.ToString(); } finally @@ -125,24 +125,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2) } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -182,6 +169,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) sb.Append(arg3); } + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + return sb.ToString(); } finally @@ -191,24 +191,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -261,6 +248,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 ar sb.Append(arg4); } + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + return sb.ToString(); } finally @@ -270,24 +270,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 ar } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -353,6 +340,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T sb.Append(arg5); } + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + return sb.ToString(); } finally @@ -362,24 +362,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -458,6 +445,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg sb.Append(arg6); } + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + return sb.ToString(); } finally @@ -467,24 +467,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -576,6 +563,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 sb.Append(arg7); } + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + return sb.ToString(); } finally @@ -585,24 +585,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -707,6 +694,19 @@ public static string Concat(T0 arg0, T1 arg1 sb.Append(arg8); } + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + return sb.ToString(); } finally @@ -716,24 +716,11 @@ public static string Concat(T0 arg0, T1 arg1 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -851,6 +838,19 @@ public static string Concat(T0 arg0, T1 sb.Append(arg9); } + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + return sb.ToString(); } finally @@ -860,24 +860,11 @@ public static string Concat(T0 arg0, T1 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1008,6 +995,19 @@ public static string Concat(T0 arg0 sb.Append(arg10); } + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + return sb.ToString(); } finally @@ -1017,24 +1017,11 @@ public static string Concat(T0 arg0 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1178,6 +1165,19 @@ public static string Concat(T0 sb.Append(arg11); } + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + return sb.ToString(); } finally @@ -1187,24 +1187,11 @@ public static string Concat(T0 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1361,6 +1348,19 @@ public static string Concat(ref arg13)); + } + else if (typeof(T13) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else + { + sb.Append(arg13); + } + return sb.ToString(); } finally @@ -1370,24 +1370,11 @@ public static string ConcatConcatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1557,6 +1544,19 @@ public static string Concat(ref arg14)); + } + else if (typeof(T14) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else + { + sb.Append(arg14); + } + return sb.ToString(); } finally @@ -1566,24 +1566,11 @@ public static string ConcatConcatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1766,6 +1753,19 @@ public static string Concat(ref arg15)); + } + else if (typeof(T15) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg15)); + } + else + { + sb.Append(arg15); + } + return sb.ToString(); } finally @@ -1775,24 +1775,11 @@ public static string ConcatConcatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1988,6 +1975,19 @@ public static string Concat(ref arg16)); + } + else if (typeof(T16) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg16)); + } + else + { + sb.Append(arg16); + } + return sb.ToString(); } finally diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs index d421e182..294862ca 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs @@ -6,12 +6,12 @@ public static partial class ZString { /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0) + public static string Format(string format, T1 arg1) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0); + sb.AppendFormat(format, arg1); return sb.ToString(); } finally @@ -22,12 +22,12 @@ public static string Format(string format, T0 arg0) /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1) + public static string Format(string format, T1 arg1, T2 arg2) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1); + sb.AppendFormat(format, arg1, arg2); return sb.ToString(); } finally @@ -38,12 +38,12 @@ public static string Format(string format, T0 arg0, T1 arg1) /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2); + sb.AppendFormat(format, arg1, arg2, arg3); return sb.ToString(); } finally @@ -54,12 +54,12 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2 /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3); + sb.AppendFormat(format, arg1, arg2, arg3, arg4); return sb.ToString(); } finally @@ -70,12 +70,12 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5); return sb.ToString(); } finally @@ -86,12 +86,12 @@ public static string Format(string format, T0 arg0, T1 arg1, /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6); return sb.ToString(); } finally @@ -102,12 +102,12 @@ public static string Format(string format, T0 arg0, T1 a /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); return sb.ToString(); } finally @@ -118,12 +118,12 @@ public static string Format(string format, T0 arg0, /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); return sb.ToString(); } finally @@ -134,12 +134,12 @@ public static string Format(string format, T0 ar /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); return sb.ToString(); } finally @@ -150,12 +150,12 @@ public static string Format(string format, T /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); return sb.ToString(); } finally @@ -166,12 +166,12 @@ public static string Format(string forma /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); return sb.ToString(); } finally @@ -182,12 +182,12 @@ public static string Format(string /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); return sb.ToString(); } finally @@ -198,12 +198,12 @@ public static string Format(st /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); return sb.ToString(); } finally @@ -214,12 +214,12 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); return sb.ToString(); } finally @@ -230,12 +230,12 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); return sb.ToString(); } finally @@ -246,12 +246,12 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); return sb.ToString(); } finally diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs new file mode 100644 index 00000000..9d726f64 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs @@ -0,0 +1,168 @@ +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public static partial class ZString + { + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs new file mode 100644 index 00000000..c2fc77be --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs @@ -0,0 +1,3234 @@ +using System.Runtime.CompilerServices; +using System.Buffers; +using System; + +namespace Cysharp.Text +{ + public static partial class ZString + { + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 12: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 12: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 13: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 12: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 13: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 14: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 12: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 13: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 14: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 15: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg16)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 5a94d147..f8ddaee2 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -1,12 +1,14 @@ using System; -using System.Buffers; using System.Collections.Generic; -using System.Runtime.CompilerServices; +using System.Linq; +using System.Text; namespace Cysharp.Text { public static partial class ZString { + static Encoding UTF8NoBom = new UTF8Encoding(false); + /// Create the Utf16 string StringBuilder. public static Utf16ValueStringBuilder CreateStringBuilder() { @@ -125,6 +127,29 @@ public static string Join(string separator, params T[] values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(string separator, List values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, ReadOnlySpan values) { @@ -147,6 +172,26 @@ public static string Join(string separator, ReadOnlySpan values) } } + public static string Join(string separator, ICollection values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(string separator, IList values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(string separator, IReadOnlyList values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(string separator, IReadOnlyCollection values) + { + return Join(separator, values.AsEnumerable()); + } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, IEnumerable values) { diff --git a/src/ZString/ExceptionUtil.cs b/src/ZString/ExceptionUtil.cs new file mode 100644 index 00000000..64413691 --- /dev/null +++ b/src/ZString/ExceptionUtil.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + internal static class ExceptionUtil + { + internal static void ThrowArgumentException(string paramName) + { + throw new ArgumentException("Can't format argument.", paramName); + } + + internal static void ThrowFormatException() + { + throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); + } + } +} diff --git a/src/ZString/PreparedFormat.cs b/src/ZString/PreparedFormat.cs index 2948f92b..4759b589 100644 --- a/src/ZString/PreparedFormat.cs +++ b/src/ZString/PreparedFormat.cs @@ -1,19 +1,20 @@ using System; -using System.Collections.Generic; +using System.Text; +using System.Buffers; namespace Cysharp.Text { - public sealed partial class PreparedFormat + public sealed partial class Utf16PreparedFormat { public string FormatString { get; } public int MinSize { get; } readonly FormatSegment[] segments; - public PreparedFormat(string format) + public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = Parse(format); + this.segments = PreparedFormatHelper.Parse(format, false); var size = 0; foreach (var item in segments) @@ -26,45 +27,107 @@ public PreparedFormat(string format) this.MinSize = size; } - // TODO:test 2args. - public string Format(T0 arg0, T1 arg1) + public string Format(T1 arg1) { - // using (var sb = new Utf16ValueStringBuilder(true)) - + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + public void FormatTo(ref TBufferWriter sb, T1 arg1) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) { - while (true) + if (!item.IsFormatArgument) { - var buffer = sb.AsArraySegment().Array; - if (TryFormat(buffer, arg0, arg1, out var written)) - { - return new string(buffer, 0, written); - } - else + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) { - // sb.ad + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; } } } } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; - public bool TryFormat(Span span, T0 arg0, T1 arg1, out int written) + public Utf16PreparedFormat(string format) { - written = 0; + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } - if (span.Length < MinSize) + public string Format(T1 arg1, T2 arg2) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2); + return sb.ToString(); + } + finally { - return false; + sb.Dispose(); } + } + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) + where TBufferWriter : IBufferWriter + { var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var span = sb.GetSpan(item.Count); strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - span = span.Slice(item.Count); - written += item.Count; + sb.Advance(item.Count); } else { @@ -72,24 +135,32 @@ public bool TryFormat(Span span, T0 arg0, T1 arg1, out int written { case 0: { - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg0, span, out var argWritten, item.FormatString.AsSpan())) + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) { - written += argWritten; - return false; + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } } - span = span.Slice(written); - written += argWritten; + sb.Advance(argWritten); break; } case 1: { - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) { - written += argWritten; - return false; + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } } - span = span.Slice(written); - written += argWritten; + sb.Advance(argWritten); break; } default: @@ -97,87 +168,5904 @@ public bool TryFormat(Span span, T0 arg0, T1 arg1, out int written } } } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; - return true; + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; } - FormatSegment[] Parse(string format) + public string Format(T1 arg1, T2 arg2, T3 arg3) { - var list = new List(); + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } - var copyFrom = 0; - for (int i = 0; i < format.Length; i++) + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) { - if (format[i] == '{') + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else { - // escape. - if (i == format.Length - 1) + switch (item.FormatIndex) { - throw new FormatException("invalid format"); + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; } + } + } + } + } - if (i != format.Length && format[i + 1] == '{') - { - var size = i - copyFrom; - list.Add(new FormatSegment(copyFrom, size, false, 0, null)); - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; - } - else - { - var size = i - copyFrom; - list.Add(new FormatSegment(copyFrom, size, false, 0, null)); - } + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } - // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - list.Add(new FormatSegment(0, 0, true, indexParse.Index, indexParse.FormatString.ToString())); + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); } - else if (format[i] == '}') + else { - if (i != format.Length && format[i + 1] == '}') + switch (item.FormatIndex) { - var size = i - copyFrom; - list.Add(new FormatSegment(copyFrom, size, false, 0, null)); - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; } } } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + var size = 0; + foreach (var item in segments) { - // final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) + if (!item.IsFormatArgument) { - list.Add(new FormatSegment(copyFrom, copyLength, false, 0, null)); + size += item.Count; } } - - return list.ToArray(); + this.MinSize = size; } - readonly struct FormatSegment + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { - public readonly int Offset; - public readonly int Count; - public readonly bool IsFormatArgument; - public readonly int FormatIndex; - public readonly string FormatString; + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } - public FormatSegment(int offset, int count, bool isFormatArgument, int formatIndex, string formatString) + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) { - Offset = offset; - Count = count; - IsFormatArgument = isFormatArgument; - FormatIndex = formatIndex; - FormatString = formatString; + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } } } } -} + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + case 14: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf16PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + + public Utf16PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, false); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + where TBufferWriter : IBufferWriter + { + var strSpan = FormatString.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + case 14: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + sb.Advance(argWritten); + break; + } + case 15: + { + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out var argWritten, item.FormatString.AsSpan())) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out argWritten, item.FormatString.AsSpan())) + { + ExceptionUtil.ThrowArgumentException(nameof(arg16)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + case 14: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + + public sealed partial class Utf8PreparedFormat + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; + readonly byte[] utf8Format; + + public Utf8PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, true); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; + this.utf8Format = Encoding.UTF8.GetBytes(format); + } + + public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + FormatTo(ref sb, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + where TBufferWriter : IBufferWriter + { + var strSpan = utf8Format.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { + case 0: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + sb.Advance(argWritten); + break; + } + case 1: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + sb.Advance(argWritten); + break; + } + case 2: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + sb.Advance(argWritten); + break; + } + case 3: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + sb.Advance(argWritten); + break; + } + case 4: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + sb.Advance(argWritten); + break; + } + case 5: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + sb.Advance(argWritten); + break; + } + case 6: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + sb.Advance(argWritten); + break; + } + case 7: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + sb.Advance(argWritten); + break; + } + case 8: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + sb.Advance(argWritten); + break; + } + case 9: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + sb.Advance(argWritten); + break; + } + case 10: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + sb.Advance(argWritten); + break; + } + case 11: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + sb.Advance(argWritten); + break; + } + case 12: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + sb.Advance(argWritten); + break; + } + case 13: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + sb.Advance(argWritten); + break; + } + case 14: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + sb.Advance(argWritten); + break; + } + case 15: + { + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out var argWritten, item.StandardFormat)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out argWritten, item.StandardFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg16)); + } + } + sb.Advance(argWritten); + break; + } + default: + break; + } + } + } + } + } + +} \ No newline at end of file diff --git a/src/ZString/PreparedFormat.tt b/src/ZString/PreparedFormat.tt new file mode 100644 index 00000000..df6e15d0 --- /dev/null +++ b/src/ZString/PreparedFormat.tt @@ -0,0 +1,119 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); + } + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + (x + 1))); + } + + string[] utfTypes = new [] { "Utf16", "Utf8" }; +#> +using System; +using System.Text; +using System.Buffers; + +namespace Cysharp.Text +{ +<# foreach(var utf in utfTypes) { var isUtf16 = (utf == "Utf16"); #> +<# for(var i = 1; i <= 16; i++) { #> + public sealed partial class <#= utf #>PreparedFormat<<#= CreateTypeArgument(i) #>> + { + public string FormatString { get; } + public int MinSize { get; } + + readonly FormatSegment[] segments; +<# if(!isUtf16) { #> + readonly byte[] utf8Format; +<# } #> + + public <#= utf #>PreparedFormat(string format) + { + this.FormatString = format; + this.segments = PreparedFormatHelper.Parse(format, <#= (utf == "Utf16" ? false : true).ToString().ToLower() #>); + + var size = 0; + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + size += item.Count; + } + } + this.MinSize = size; +<# if(!isUtf16) { #> + this.utf8Format = Encoding.UTF8.GetBytes(format); +<# } #> + } + + public string Format(<#= CreateParameters(i) #>) + { + var sb = new <#= utf #>ValueStringBuilder(true); + try + { + FormatTo(ref sb, <#= CreateParameterNames(i) #>); + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + public void FormatTo(ref TBufferWriter sb, <#= CreateParameters(i) #>) + where TBufferWriter : IBufferWriter<<#= isUtf16 ? "char" : "byte" #>> + { + var strSpan = <#= isUtf16 ? "FormatString" : "utf8Format" #>.AsSpan(); + foreach (var item in segments) + { + if (!item.IsFormatArgument) + { + var span = sb.GetSpan(item.Count); + strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + sb.Advance(item.Count); + } + else + { + switch (item.FormatIndex) + { +<# for(var j = 0; j < i; j++) { #> + case <#= j #>: + { + var span = sb.GetSpan(0); + if (!<#= utf #>ValueStringBuilder.FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, span, out var argWritten, <#= isUtf16 ? "item.FormatString.AsSpan()" : "item.StandardFormat" #>)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!<#= utf #>ValueStringBuilder.FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, span, out argWritten, <#= isUtf16 ? "item.FormatString.AsSpan()" : "item.StandardFormat" #>)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg<#= j + 1 #>)); + } + } + sb.Advance(argWritten); + break; + } +<# } // for(j) #> + default: + break; + } + } + } + } + } + +<# } // for(i) #> +<# } // foreach(utf) #> +} \ No newline at end of file diff --git a/src/ZString/PreparedFormatHelper.cs b/src/ZString/PreparedFormatHelper.cs new file mode 100644 index 00000000..60bdcfd9 --- /dev/null +++ b/src/ZString/PreparedFormatHelper.cs @@ -0,0 +1,109 @@ +using System; +using System.Buffers; +using System.Collections.Generic; + +namespace Cysharp.Text +{ + internal static class PreparedFormatHelper + { + internal static FormatSegment[] Parse(string format, bool withStandardFormat) + { + var list = new List(); + + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + if (size != 0) + { + list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); + } + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + if (size != 0) + { + list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); + } + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + list.Add(new FormatSegment(0, 0, true, indexParse.Index, indexParse.FormatString.ToString(), withStandardFormat)); + + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + if (size != 0) + { + list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); + } + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + } + + { + // final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + list.Add(new FormatSegment(copyFrom, copyLength, false, 0, null, withStandardFormat)); + } + } + + return list.ToArray(); + } + } + + + internal readonly struct FormatSegment + { + public readonly int Offset; + public readonly int Count; + public readonly bool IsFormatArgument; + public readonly int FormatIndex; + public readonly string FormatString; + + // Utf8 + public readonly StandardFormat StandardFormat; + + public FormatSegment(int offset, int count, bool isFormatArgument, int formatIndex, string formatString, bool utf8) + { + Offset = offset; + Count = count; + IsFormatArgument = isFormatArgument; + FormatIndex = formatIndex; + FormatString = formatString; + if (utf8) + { + StandardFormat = (formatString != null) ? StandardFormat.Parse(formatString) : default; + } + else + { + StandardFormat = default; + } + } + } +} diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 6eae9735..95caf7b4 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -5,7 +5,7 @@ namespace Cysharp.Text public partial struct Utf16ValueStringBuilder { /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0) + public void AppendFormat(string format, T1 arg1) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -17,7 +17,7 @@ public void AppendFormat(string format, T0 arg0) { throw new FormatException("invalid format"); } - + if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; @@ -44,12 +44,12 @@ public void AppendFormat(string format, T0 arg0) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -93,7 +93,7 @@ public void AppendFormat(string format, T0 arg0) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1) + public void AppendFormat(string format, T1 arg1, T2 arg2) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -132,12 +132,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -145,12 +145,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -194,7 +194,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -233,12 +233,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -246,12 +246,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -259,12 +259,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -308,7 +308,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -347,12 +347,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -360,12 +360,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -373,12 +373,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -386,12 +386,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg3)); + ThrowArgumentException(nameof(arg4)); } } index += written; @@ -435,7 +435,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -474,12 +474,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -487,12 +487,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -500,12 +500,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -513,12 +513,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg3)); + ThrowArgumentException(nameof(arg4)); } } index += written; @@ -526,12 +526,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg4)); + ThrowArgumentException(nameof(arg5)); } } index += written; @@ -575,7 +575,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -613,19 +613,6 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -638,7 +625,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -651,7 +638,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -664,7 +651,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -677,7 +664,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -690,6 +677,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -728,7 +728,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -766,19 +766,6 @@ public void AppendFormat(string format, T0 arg0, T1 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -791,7 +778,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -804,7 +791,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -817,7 +804,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -830,7 +817,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -843,7 +830,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -856,6 +843,19 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -894,7 +894,7 @@ public void AppendFormat(string format, T0 arg0, T1 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -932,19 +932,6 @@ public void AppendFormat(string format, T0 arg0, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -957,7 +944,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -970,7 +957,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -983,7 +970,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -996,7 +983,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1009,7 +996,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1022,7 +1009,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1035,6 +1022,19 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1073,7 +1073,7 @@ public void AppendFormat(string format, T0 arg0, } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1111,19 +1111,6 @@ public void AppendFormat(string format, T0 a switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1136,7 +1123,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1149,7 +1136,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1162,7 +1149,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1175,7 +1162,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1188,7 +1175,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1201,7 +1188,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1214,7 +1201,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1227,6 +1214,19 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1265,7 +1265,7 @@ public void AppendFormat(string format, T0 a } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1303,19 +1303,6 @@ public void AppendFormat(string format, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1328,7 +1315,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1341,7 +1328,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1354,7 +1341,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1367,7 +1354,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1380,7 +1367,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1393,7 +1380,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1406,7 +1393,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1419,7 +1406,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1432,6 +1419,19 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1470,7 +1470,7 @@ public void AppendFormat(string format, } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1509,12 +1509,12 @@ public void AppendFormat(string for { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -1522,20 +1522,7 @@ public void AppendFormat(string for } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } - case 2: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) @@ -1546,7 +1533,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1559,7 +1546,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1572,7 +1559,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1585,7 +1572,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1598,7 +1585,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1611,7 +1598,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1624,7 +1611,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1637,7 +1624,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1650,6 +1637,19 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1688,7 +1688,7 @@ public void AppendFormat(string for } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1726,19 +1726,6 @@ public void AppendFormat(strin switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1751,7 +1738,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1764,7 +1751,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1777,7 +1764,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1790,7 +1777,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1803,7 +1790,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1816,7 +1803,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1829,7 +1816,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1842,7 +1829,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1855,7 +1842,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1868,7 +1855,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 11: + case 10: { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1881,6 +1868,19 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1919,7 +1919,7 @@ public void AppendFormat(strin } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1957,19 +1957,6 @@ public void AppendFormat( switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1982,7 +1969,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -1995,7 +1982,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2008,7 +1995,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2021,7 +2008,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2034,7 +2021,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2047,7 +2034,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2060,7 +2047,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2073,7 +2060,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2086,7 +2073,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2099,7 +2086,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 11: + case 10: { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2112,7 +2099,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 12: + case 11: { if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2125,6 +2112,19 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2163,7 +2163,7 @@ public void AppendFormat( } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2201,19 +2201,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2226,7 +2213,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2239,7 +2226,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2252,7 +2239,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2265,7 +2252,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2278,7 +2265,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2291,7 +2278,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2304,7 +2291,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2317,7 +2304,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2330,7 +2317,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2343,7 +2330,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2356,7 +2343,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2369,7 +2356,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2382,6 +2369,19 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2420,7 +2420,7 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2458,19 +2458,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2483,7 +2470,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2496,7 +2483,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2509,7 +2496,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2522,7 +2509,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2535,7 +2522,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2548,7 +2535,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2561,7 +2548,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2574,7 +2561,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2587,7 +2574,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2600,7 +2587,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2613,7 +2600,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2626,7 +2613,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2639,7 +2626,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2652,6 +2639,19 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2690,7 +2690,7 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2728,19 +2728,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2753,7 +2740,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2766,7 +2753,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2779,7 +2766,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2792,7 +2779,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2805,7 +2792,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2818,7 +2805,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2831,7 +2818,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2844,7 +2831,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2857,7 +2844,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2870,7 +2857,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2883,7 +2870,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2896,7 +2883,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2909,7 +2896,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2922,7 +2909,7 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) { @@ -2935,6 +2922,19 @@ public void AppendFormat.TryFormatDelegate(arg16, buffer.AsSpan(index), out var written, indexParse.FormatString)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out written, indexParse.FormatString)) + { + ThrowArgumentException(nameof(arg16)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt index 901e030f..8fadad24 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt @@ -7,12 +7,12 @@ <# static string CreateTypeArgument(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); } static string CreateParameters(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); } #> @@ -64,12 +64,12 @@ namespace Cysharp.Text <# for(var j = 0; j < i; j++) { #> case <#= j #>: { - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out var written, indexParse.FormatString)) + if (!FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer.AsSpan(index), out var written, indexParse.FormatString)) { Grow(written); - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, indexParse.FormatString)) + if (!FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer.AsSpan(index), out written, indexParse.FormatString)) { - ThrowArgumentException(nameof(arg<#= j #>)); + ThrowArgumentException(nameof(arg<#= j + 1 #>)); } } index += written; diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index e20d28cb..954e2f17 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -86,7 +86,7 @@ public void Dispose() index = 0; } - void TryGrow(int sizeHint) + public void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) { @@ -94,7 +94,7 @@ void TryGrow(int sizeHint) } } - void Grow(int sizeHint = 0) + public void Grow(int sizeHint = 0) { var nextSize = buffer.Length * 2; if (sizeHint != 0) diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index b68e7d61..dd60d0c8 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -6,7 +6,7 @@ namespace Cysharp.Text public partial struct Utf8ValueStringBuilder { /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0) + public void AppendFormat(string format, T1 arg1) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -44,12 +44,12 @@ public void AppendFormat(string format, T0 arg0) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -90,7 +90,7 @@ public void AppendFormat(string format, T0 arg0) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1) + public void AppendFormat(string format, T1 arg1, T2 arg2) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -128,12 +128,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -141,12 +141,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -187,7 +187,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -225,12 +225,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -238,12 +238,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -251,12 +251,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -297,7 +297,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2) } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -335,12 +335,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -348,12 +348,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -361,12 +361,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -374,12 +374,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg3)); + ThrowArgumentException(nameof(arg4)); } } index += written; @@ -420,7 +420,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -458,12 +458,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -471,12 +471,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg1)); + ThrowArgumentException(nameof(arg2)); } } index += written; @@ -484,12 +484,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 2: { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg2)); + ThrowArgumentException(nameof(arg3)); } } index += written; @@ -497,12 +497,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 3: { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg3)); + ThrowArgumentException(nameof(arg4)); } } index += written; @@ -510,12 +510,12 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } case 4: { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg4)); + ThrowArgumentException(nameof(arg5)); } } index += written; @@ -556,7 +556,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1, T2 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -593,19 +593,6 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -618,7 +605,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -631,7 +618,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -644,7 +631,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -657,7 +644,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -670,6 +657,19 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 index += written; goto NEXT_LOOP; } + case 5: + { + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg6)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -705,7 +705,7 @@ public void AppendFormat(string format, T0 arg0, T1 arg1 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -742,19 +742,6 @@ public void AppendFormat(string format, T0 arg0, T1 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -767,7 +754,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -780,7 +767,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -793,7 +780,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -806,7 +793,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -819,7 +806,7 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -832,6 +819,19 @@ public void AppendFormat(string format, T0 arg0, T1 index += written; goto NEXT_LOOP; } + case 6: + { + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg7)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -867,7 +867,7 @@ public void AppendFormat(string format, T0 arg0, T1 } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -904,19 +904,6 @@ public void AppendFormat(string format, T0 arg0, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -929,7 +916,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -942,7 +929,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -955,7 +942,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -968,7 +955,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -981,7 +968,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -994,7 +981,7 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1007,6 +994,19 @@ public void AppendFormat(string format, T0 arg0, index += written; goto NEXT_LOOP; } + case 7: + { + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg8)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1042,7 +1042,7 @@ public void AppendFormat(string format, T0 arg0, } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1079,19 +1079,6 @@ public void AppendFormat(string format, T0 a switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1104,7 +1091,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1117,7 +1104,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1130,7 +1117,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1143,7 +1130,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1156,7 +1143,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1169,7 +1156,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1182,7 +1169,7 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1195,6 +1182,19 @@ public void AppendFormat(string format, T0 a index += written; goto NEXT_LOOP; } + case 8: + { + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg9)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1230,7 +1230,7 @@ public void AppendFormat(string format, T0 a } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1267,19 +1267,6 @@ public void AppendFormat(string format, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1292,7 +1279,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1305,7 +1292,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1318,7 +1305,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1331,7 +1318,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1344,7 +1331,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1357,7 +1344,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1370,7 +1357,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1383,7 +1370,7 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1396,6 +1383,19 @@ public void AppendFormat(string format, index += written; goto NEXT_LOOP; } + case 9: + { + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg10)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1431,7 +1431,7 @@ public void AppendFormat(string format, } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1469,12 +1469,12 @@ public void AppendFormat(string for { case 0: { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg0)); + ThrowArgumentException(nameof(arg1)); } } index += written; @@ -1482,20 +1482,7 @@ public void AppendFormat(string for } case 1: { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } - case 2: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) @@ -1506,7 +1493,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1519,7 +1506,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1532,7 +1519,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1545,7 +1532,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1558,7 +1545,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1571,7 +1558,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1584,7 +1571,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1597,7 +1584,7 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1610,6 +1597,19 @@ public void AppendFormat(string for index += written; goto NEXT_LOOP; } + case 10: + { + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg11)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1645,7 +1645,7 @@ public void AppendFormat(string for } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1682,19 +1682,6 @@ public void AppendFormat(strin switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1707,7 +1694,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1720,7 +1707,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1733,7 +1720,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1746,7 +1733,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1759,7 +1746,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1772,7 +1759,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1785,7 +1772,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1798,7 +1785,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1811,7 +1798,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1824,7 +1811,7 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } - case 11: + case 10: { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1837,6 +1824,19 @@ public void AppendFormat(strin index += written; goto NEXT_LOOP; } + case 11: + { + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg12)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -1872,7 +1872,7 @@ public void AppendFormat(strin } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -1909,19 +1909,6 @@ public void AppendFormat( switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1934,7 +1921,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 2: + case 1: { if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1947,7 +1934,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 3: + case 2: { if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1960,7 +1947,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 4: + case 3: { if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1973,7 +1960,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 5: + case 4: { if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1986,7 +1973,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 6: + case 5: { if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -1999,7 +1986,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 7: + case 6: { if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2012,7 +1999,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 8: + case 7: { if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2025,7 +2012,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 9: + case 8: { if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2038,7 +2025,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 10: + case 9: { if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2051,7 +2038,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 11: + case 10: { if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2064,7 +2051,7 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } - case 12: + case 11: { if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2077,6 +2064,19 @@ public void AppendFormat( index += written; goto NEXT_LOOP; } + case 12: + { + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg13)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2112,7 +2112,7 @@ public void AppendFormat( } /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2149,19 +2149,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2174,7 +2161,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2187,7 +2174,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2200,7 +2187,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2213,7 +2200,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2226,7 +2213,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2239,7 +2226,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2252,7 +2239,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2265,7 +2252,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2278,7 +2265,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2291,7 +2278,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2304,7 +2291,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2317,7 +2304,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2330,6 +2317,19 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg14)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2365,7 +2365,7 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2402,19 +2402,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2427,7 +2414,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2440,7 +2427,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2453,7 +2440,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2466,7 +2453,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2479,7 +2466,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2492,7 +2479,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2505,7 +2492,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2518,7 +2505,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2531,7 +2518,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2544,7 +2531,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2557,7 +2544,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2570,7 +2557,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2583,7 +2570,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2596,6 +2583,19 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg15)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; @@ -2631,7 +2631,7 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. - public void AppendFormat(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var copyFrom = 0; for (int i = 0; i < format.Length; i++) @@ -2668,19 +2668,6 @@ public void AppendFormat.TryFormatDelegate(arg0, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg0, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg0)); - } - } - index += written; - goto NEXT_LOOP; - } - case 1: { if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2693,7 +2680,7 @@ public void AppendFormat.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2706,7 +2693,7 @@ public void AppendFormat.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2719,7 +2706,7 @@ public void AppendFormat.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2732,7 +2719,7 @@ public void AppendFormat.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2745,7 +2732,7 @@ public void AppendFormat.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2758,7 +2745,7 @@ public void AppendFormat.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2771,7 +2758,7 @@ public void AppendFormat.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2784,7 +2771,7 @@ public void AppendFormat.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2797,7 +2784,7 @@ public void AppendFormat.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2810,7 +2797,7 @@ public void AppendFormat.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2823,7 +2810,7 @@ public void AppendFormat.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2836,7 +2823,7 @@ public void AppendFormat.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2849,7 +2836,7 @@ public void AppendFormat.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2862,7 +2849,7 @@ public void AppendFormat.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) { @@ -2875,6 +2862,19 @@ public void AppendFormat.TryFormatDelegate(arg16, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(nameof(arg16)); + } + } + index += written; + goto NEXT_LOOP; + } default: ThrowFormatException(); break; diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt index a831264b..a9ef706c 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt @@ -7,18 +7,12 @@ <# static string CreateTypeArgument(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); } static string CreateParameters(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); - } - - - static string CreateParameterNames(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); } #> using System; @@ -69,12 +63,12 @@ namespace Cysharp.Text <# for(var j = 0; j < i; j++) { #> case <#= j #>: { - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out var written, writeFormat)) + if (!FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer.AsSpan(index), out var written, writeFormat)) { Grow(written); - if (!FormatterCache>.TryFormatDelegate(arg<#= j #>, buffer.AsSpan(index), out written, writeFormat)) + if (!FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer.AsSpan(index), out written, writeFormat)) { - ThrowArgumentException(nameof(arg<#= j #>)); + ThrowArgumentException(nameof(arg<#= j + 1 #>)); } } index += written; diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 9beee4e3..3c664f4b 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -93,7 +93,7 @@ public void Dispose() index = 0; } - void TryGrow(int sizeHint) + public void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) { @@ -101,7 +101,7 @@ void TryGrow(int sizeHint) } } - void Grow(int sizeHint = 0) + public void Grow(int sizeHint = 0) { var nextSize = buffer.Length * 2; if (sizeHint != 0) @@ -207,6 +207,14 @@ public void AppendLine(T value) // Output + /// Copy inner buffer to the bufferWriter. + public void CopyTo(IBufferWriter bufferWriter) + { + var destination = bufferWriter.GetSpan(index); + TryCopyTo(destination, out var written); + bufferWriter.Advance(written); + } + /// Copy inner buffer to the destination span. public bool TryCopyTo(Span destination, out int bytesWritten) { @@ -281,7 +289,7 @@ public static void RegisterTryFormat(TryFormat formatMethod) FormatterCache.TryFormatDelegate = formatMethod; } - static class FormatterCache + public static class FormatterCache { public static TryFormat TryFormatDelegate; static FormatterCache() diff --git a/src/ZString/ZString.Concat.cs b/src/ZString/ZString.Concat.cs index 22a4b93f..4c20ec55 100644 --- a/src/ZString/ZString.Concat.cs +++ b/src/ZString/ZString.Concat.cs @@ -5,22 +5,22 @@ namespace Cysharp.Text public static partial class ZString { /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0) + public static string Concat(T1 arg1) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) + if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg0)); + sb.Append(Unsafe.As(ref arg1)); } - else if (typeof(T0) == typeof(int)) + else if (typeof(T1) == typeof(int)) { - sb.Append(Unsafe.As(ref arg0)); + sb.Append(Unsafe.As(ref arg1)); } else { - sb.Append(arg0); + sb.Append(arg1); } return sb.ToString(); @@ -32,35 +32,35 @@ public static string Concat(T0 arg0) } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1) + public static string Concat(T1 arg1, T2 arg2) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) + if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg0)); + sb.Append(Unsafe.As(ref arg1)); } - else if (typeof(T0) == typeof(int)) + else if (typeof(T1) == typeof(int)) { - sb.Append(Unsafe.As(ref arg0)); + sb.Append(Unsafe.As(ref arg1)); } else { - sb.Append(arg0); + sb.Append(arg1); } - if (typeof(T1) == typeof(string)) + if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + sb.Append(Unsafe.As(ref arg2)); } - else if (typeof(T1) == typeof(int)) + else if (typeof(T2) == typeof(int)) { - sb.Append(Unsafe.As(ref arg1)); + sb.Append(Unsafe.As(ref arg2)); } else { - sb.Append(arg1); + sb.Append(arg2); } return sb.ToString(); @@ -72,24 +72,11 @@ public static string Concat(T0 arg0, T1 arg1) } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2) + public static string Concat(T1 arg1, T2 arg2, T3 arg3) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -116,6 +103,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2) sb.Append(arg2); } + if (typeof(T3) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else if (typeof(T3) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg3)); + } + else + { + sb.Append(arg3); + } + return sb.ToString(); } finally @@ -125,24 +125,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2) } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -182,6 +169,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) sb.Append(arg3); } + if (typeof(T4) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else if (typeof(T4) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg4)); + } + else + { + sb.Append(arg4); + } + return sb.ToString(); } finally @@ -191,24 +191,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3) } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -261,6 +248,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 ar sb.Append(arg4); } + if (typeof(T5) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else if (typeof(T5) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg5)); + } + else + { + sb.Append(arg5); + } + return sb.ToString(); } finally @@ -270,24 +270,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 ar } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -353,6 +340,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T sb.Append(arg5); } + if (typeof(T6) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else if (typeof(T6) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg6)); + } + else + { + sb.Append(arg6); + } + return sb.ToString(); } finally @@ -362,24 +362,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg2, T } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -458,6 +445,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg sb.Append(arg6); } + if (typeof(T7) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else if (typeof(T7) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg7)); + } + else + { + sb.Append(arg7); + } + return sb.ToString(); } finally @@ -467,24 +467,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 arg } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -576,6 +563,19 @@ public static string Concat(T0 arg0, T1 arg1, T2 sb.Append(arg7); } + if (typeof(T8) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else if (typeof(T8) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg8)); + } + else + { + sb.Append(arg8); + } + return sb.ToString(); } finally @@ -585,24 +585,11 @@ public static string Concat(T0 arg0, T1 arg1, T2 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -707,6 +694,19 @@ public static string Concat(T0 arg0, T1 arg1 sb.Append(arg8); } + if (typeof(T9) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else if (typeof(T9) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg9)); + } + else + { + sb.Append(arg9); + } + return sb.ToString(); } finally @@ -716,24 +716,11 @@ public static string Concat(T0 arg0, T1 arg1 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -851,6 +838,19 @@ public static string Concat(T0 arg0, T1 sb.Append(arg9); } + if (typeof(T10) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else if (typeof(T10) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg10)); + } + else + { + sb.Append(arg10); + } + return sb.ToString(); } finally @@ -860,24 +860,11 @@ public static string Concat(T0 arg0, T1 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1008,6 +995,19 @@ public static string Concat(T0 arg0 sb.Append(arg10); } + if (typeof(T11) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else if (typeof(T11) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg11)); + } + else + { + sb.Append(arg11); + } + return sb.ToString(); } finally @@ -1017,24 +1017,11 @@ public static string Concat(T0 arg0 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1178,6 +1165,19 @@ public static string Concat(T0 sb.Append(arg11); } + if (typeof(T12) == typeof(string)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else if (typeof(T12) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg12)); + } + else + { + sb.Append(arg12); + } + return sb.ToString(); } finally @@ -1187,24 +1187,11 @@ public static string Concat(T0 } /// Concatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1361,6 +1348,19 @@ public static string Concat(ref arg13)); + } + else if (typeof(T13) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg13)); + } + else + { + sb.Append(arg13); + } + return sb.ToString(); } finally @@ -1370,24 +1370,11 @@ public static string ConcatConcatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1557,6 +1544,19 @@ public static string Concat(ref arg14)); + } + else if (typeof(T14) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg14)); + } + else + { + sb.Append(arg14); + } + return sb.ToString(); } finally @@ -1566,24 +1566,11 @@ public static string ConcatConcatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1766,6 +1753,19 @@ public static string Concat(ref arg15)); + } + else if (typeof(T15) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg15)); + } + else + { + sb.Append(arg15); + } + return sb.ToString(); } finally @@ -1775,24 +1775,11 @@ public static string ConcatConcatenates the string representation of some specified objects. - public static string Concat(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var sb = new Utf16ValueStringBuilder(true); try { - if (typeof(T0) == typeof(string)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else if (typeof(T0) == typeof(int)) - { - sb.Append(Unsafe.As(ref arg0)); - } - else - { - sb.Append(arg0); - } - if (typeof(T1) == typeof(string)) { sb.Append(Unsafe.As(ref arg1)); @@ -1988,6 +1975,19 @@ public static string Concat(ref arg16)); + } + else if (typeof(T16) == typeof(int)) + { + sb.Append(Unsafe.As(ref arg16)); + } + else + { + sb.Append(arg16); + } + return sb.ToString(); } finally diff --git a/src/ZString/ZString.Concat.tt b/src/ZString/ZString.Concat.tt index 5eb68bfc..664d0207 100644 --- a/src/ZString/ZString.Concat.tt +++ b/src/ZString/ZString.Concat.tt @@ -7,12 +7,12 @@ <# static string CreateTypeArgument(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); } static string CreateParameters(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); } #> @@ -30,17 +30,17 @@ namespace Cysharp.Text try { <# for(var j = 0; j < i; j++) { #> - if (typeof(T<#= j #>) == typeof(string)) + if (typeof(T<#= j + 1 #>) == typeof(string)) { - sb.Append(Unsafe.As, string>(ref arg<#= j #>)); + sb.Append(Unsafe.As, string>(ref arg<#= j + 1 #>)); } - else if (typeof(T<#= j #>) == typeof(int)) + else if (typeof(T<#= j + 1 #>) == typeof(int)) { - sb.Append(Unsafe.As, int>(ref arg<#= j #>)); + sb.Append(Unsafe.As, int>(ref arg<#= j + 1 #>)); } else { - sb.Append(arg<#= j #>); + sb.Append(arg<#= j + 1 #>); } <# } #> diff --git a/src/ZString/ZString.Format.cs b/src/ZString/ZString.Format.cs index d421e182..294862ca 100644 --- a/src/ZString/ZString.Format.cs +++ b/src/ZString/ZString.Format.cs @@ -6,12 +6,12 @@ public static partial class ZString { /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0) + public static string Format(string format, T1 arg1) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0); + sb.AppendFormat(format, arg1); return sb.ToString(); } finally @@ -22,12 +22,12 @@ public static string Format(string format, T0 arg0) /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1) + public static string Format(string format, T1 arg1, T2 arg2) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1); + sb.AppendFormat(format, arg1, arg2); return sb.ToString(); } finally @@ -38,12 +38,12 @@ public static string Format(string format, T0 arg0, T1 arg1) /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2); + sb.AppendFormat(format, arg1, arg2, arg3); return sb.ToString(); } finally @@ -54,12 +54,12 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 arg2 /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3); + sb.AppendFormat(format, arg1, arg2, arg3, arg4); return sb.ToString(); } finally @@ -70,12 +70,12 @@ public static string Format(string format, T0 arg0, T1 arg1, T2 /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5); return sb.ToString(); } finally @@ -86,12 +86,12 @@ public static string Format(string format, T0 arg0, T1 arg1, /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6); return sb.ToString(); } finally @@ -102,12 +102,12 @@ public static string Format(string format, T0 arg0, T1 a /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7); return sb.ToString(); } finally @@ -118,12 +118,12 @@ public static string Format(string format, T0 arg0, /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); return sb.ToString(); } finally @@ -134,12 +134,12 @@ public static string Format(string format, T0 ar /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); return sb.ToString(); } finally @@ -150,12 +150,12 @@ public static string Format(string format, T /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); return sb.ToString(); } finally @@ -166,12 +166,12 @@ public static string Format(string forma /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); return sb.ToString(); } finally @@ -182,12 +182,12 @@ public static string Format(string /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); return sb.ToString(); } finally @@ -198,12 +198,12 @@ public static string Format(st /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); return sb.ToString(); } finally @@ -214,12 +214,12 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); return sb.ToString(); } finally @@ -230,12 +230,12 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); return sb.ToString(); } finally @@ -246,12 +246,12 @@ public static string FormatReplaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Format(string format, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + public static string Format(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var sb = new Utf16ValueStringBuilder(true); try { - sb.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); return sb.ToString(); } finally diff --git a/src/ZString/ZString.Format.tt b/src/ZString/ZString.Format.tt index 67287387..e6449f9d 100644 --- a/src/ZString/ZString.Format.tt +++ b/src/ZString/ZString.Format.tt @@ -7,18 +7,18 @@ <# static string CreateTypeArgument(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); } static string CreateParameters(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + x + " arg" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); } static string CreateParameterNames(int i) { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + x)); + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + (x + 1))); } #> using System.Runtime.CompilerServices; diff --git a/src/ZString/ZString.Prepare.cs b/src/ZString/ZString.Prepare.cs new file mode 100644 index 00000000..90a309aa --- /dev/null +++ b/src/ZString/ZString.Prepare.cs @@ -0,0 +1,200 @@ +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public static partial class ZString + { + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat PrepareUtf16(string format) + { + return new Utf16PreparedFormat(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat PrepareUtf8(string format) + { + return new Utf8PreparedFormat(format); + } + + } +} \ No newline at end of file diff --git a/src/ZString/ZString.Prepare.tt b/src/ZString/ZString.Prepare.tt new file mode 100644 index 00000000..d3f4f72c --- /dev/null +++ b/src/ZString/ZString.Prepare.tt @@ -0,0 +1,34 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); + } +#> +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public static partial class ZString + { +<# for(var i = 1; i <= 16; i++) { #> + /// Prepare string format to avoid parse template in each operation. + public static Utf16PreparedFormat<<#= CreateTypeArgument(i) #>> PrepareUtf16<<#= CreateTypeArgument(i) #>>(string format) + { + return new Utf16PreparedFormat<<#= CreateTypeArgument(i) #>>(format); + } + + /// Prepare string format to avoid parse template in each operation. + public static Utf8PreparedFormat<<#= CreateTypeArgument(i) #>> PrepareUtf8<<#= CreateTypeArgument(i) #>>(string format) + { + return new Utf8PreparedFormat<<#= CreateTypeArgument(i) #>>(format); + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/ZString.Utf8Format.cs b/src/ZString/ZString.Utf8Format.cs new file mode 100644 index 00000000..dcf7f395 --- /dev/null +++ b/src/ZString/ZString.Utf8Format.cs @@ -0,0 +1,3250 @@ +using System.Runtime.CompilerServices; +using System.Buffers; +using System; + +namespace Cysharp.Text +{ + public static partial class ZString + { + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 12: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 12: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 13: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 12: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 13: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 14: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { + case 0: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg1)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 1: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg2)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 2: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg3)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 3: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg4)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 4: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg5)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 5: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg6)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 6: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg7)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 7: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg8)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 8: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg9)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 9: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg10)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 10: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg11)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 11: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg12)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 12: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg13)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 13: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg14)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 14: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg15)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + case 15: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg16)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + + } +} \ No newline at end of file diff --git a/src/ZString/ZString.Utf8Format.tt b/src/ZString/ZString.Utf8Format.tt new file mode 100644 index 00000000..a7b284e4 --- /dev/null +++ b/src/ZString/ZString.Utf8Format.tt @@ -0,0 +1,122 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); + } + +#> +using System.Runtime.CompilerServices; +using System.Buffers; +using System; + +namespace Cysharp.Text +{ + public static partial class ZString + { +<# for(var i = 1; i <= 16; i++) { #> + /// Replaces one or more format items in a string with the string representation of some specified values. + public static void Utf8Format<<#= CreateTypeArgument(i) #>>(IBufferWriter bufferWriter, string format, <#= CreateParameters(i) #>) + { + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + var writeFormat = StandardFormat.Parse(indexParse.FormatString); + switch (indexParse.Index) + { +<# for(var j = 0; j < i; j++) { #> + case <#= j #>: + { + var buffer = bufferWriter.GetSpan(); + if (!Utf8ValueStringBuilder.FormatterCache>.TryFormatDelegate(arg<#= j +1 #>, buffer, out var written, writeFormat)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + if (!Utf8ValueStringBuilder.FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer, out written, writeFormat)) + { + ExceptionUtil.ThrowArgumentException(nameof(arg<#= j + 1 #>)); + } + } + bufferWriter.Advance(written); + goto NEXT_LOOP; + } +<# } #> + default: + ExceptionUtil.ThrowFormatException(); + break; + } + + ExceptionUtil.ThrowFormatException(); + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer); + bufferWriter.Advance(written); + i = i + 1; // skip escaped '}' + copyFrom = i; + } + } + + NEXT_LOOP: + continue; + } + + { + // copy final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(copyLength)); + var written = UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer); + bufferWriter.Advance(written); + } + } + } + +<# } #> + } +} \ No newline at end of file diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 5a94d147..f8ddaee2 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -1,12 +1,14 @@ using System; -using System.Buffers; using System.Collections.Generic; -using System.Runtime.CompilerServices; +using System.Linq; +using System.Text; namespace Cysharp.Text { public static partial class ZString { + static Encoding UTF8NoBom = new UTF8Encoding(false); + /// Create the Utf16 string StringBuilder. public static Utf16ValueStringBuilder CreateStringBuilder() { @@ -125,6 +127,29 @@ public static string Join(string separator, params T[] values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(string separator, List values) + { + var sb = new Utf8ValueStringBuilder(true); + try + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, ReadOnlySpan values) { @@ -147,6 +172,26 @@ public static string Join(string separator, ReadOnlySpan values) } } + public static string Join(string separator, ICollection values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(string separator, IList values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(string separator, IReadOnlyList values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(string separator, IReadOnlyCollection values) + { + return Join(separator, values.AsEnumerable()); + } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, IEnumerable values) { diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index ece257ca..46ef491a 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -31,6 +31,10 @@ + + TextTemplatingFileGenerator + PreparedFormat.cs + TextTemplatingFileGenerator TextMeshProExtensions.cs @@ -75,9 +79,22 @@ TextTemplatingFileGenerator ZString.Format.cs + + TextTemplatingFileGenerator + ZString.Prepare.cs + + + TextTemplatingFileGenerator + ZString.Utf8Format.cs + + + True + True + PreparedFormat.tt + True True @@ -128,6 +145,16 @@ True ZString.Format.tt + + True + True + ZString.Prepare.tt + + + True + True + ZString.Utf8Format.tt + @@ -141,6 +168,22 @@ + + + + + + + True + True + PreparedFormat.tt + + + True + True + ZString.Utf8Format.tt + + diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index d8e30d2c..2c76cbbb 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -1,6 +1,8 @@ using Cysharp.Text; using FluentAssertions; using System; +using System.Buffers; +using System.Text; using Xunit; namespace ZStringTests @@ -21,6 +23,30 @@ void Test(string format, T0 t0, T1 t1) var expected = string.Format(format, t0, t1); actual.Should().Be(expected); } + + // Prepare + { + var actual = ZString.PrepareUtf16(format).Format(t0, t1); + var expected = string.Format(format, t0, t1); + actual.Should().Be(expected); + } + { + var sb = ZString.PrepareUtf8(format); + var actual = sb.Format(t0, t1); + var expected = string.Format(format, t0, t1); + actual.Should().Be(expected); + } + + // Direct + { +#if !NETCOREAPP2_1 + var writer = new ArrayBufferWriter(); + ZString.Utf8Format(writer, format, t0, t1); + var actual = Encoding.UTF8.GetString(writer.WrittenSpan); + var expected = string.Format(format, t0, t1); + actual.Should().Be(expected); +#endif + } } [Fact] diff --git a/tests/ZString.Tests/JoinTest.cs b/tests/ZString.Tests/JoinTest.cs index 12463d51..8f1b9cfb 100644 --- a/tests/ZString.Tests/JoinTest.cs +++ b/tests/ZString.Tests/JoinTest.cs @@ -33,5 +33,34 @@ public void JoinOverloads() ZString.Join(',', new[] { 1, 2 }.AsEnumerable()).Should().Be(string.Join(",", new[] { 1, 2 })); ZString.Join(',', new[] { 1, 2, 3 }.AsEnumerable()).Should().Be(string.Join(",", new[] { 1, 2, 3 })); } + + [Fact] + public void JoinOverloads2() + { + ZString.Join("_,_", new string[] { }.ToList()).Should().Be(string.Join("_,_", new string[0])); + ZString.Join("_,_", new[] { 1 }.ToList()).Should().Be(string.Join("_,_", new[] { 1 })); + ZString.Join("_,_", new[] { 1, 2 }.ToList()).Should().Be(string.Join("_,_", new[] { 1, 2 })); + ZString.Join("_,_", new[] { 1, 2, 3 }.ToList()).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); + + ZString.Join("_,_", (IList)new int[] { }).Should().Be(string.Join("_,_", new string[0])); + ZString.Join("_,_", (IList)new[] { 1 }).Should().Be(string.Join("_,_", new[] { 1 })); + ZString.Join("_,_", (IList)new[] { 1, 2 }).Should().Be(string.Join("_,_", new[] { 1, 2 })); + ZString.Join("_,_", (IList)new[] { 1, 2, 3 }).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); + + ZString.Join("_,_", (IReadOnlyList)new int[] { }).Should().Be(string.Join("_,_", new string[0])); + ZString.Join("_,_", (IReadOnlyList)new[] { 1 }).Should().Be(string.Join("_,_", new[] { 1 })); + ZString.Join("_,_", (IReadOnlyList)new[] { 1, 2 }).Should().Be(string.Join("_,_", new[] { 1, 2 })); + ZString.Join("_,_", (IReadOnlyList)new[] { 1, 2, 3 }).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); + + ZString.Join("_,_", (ICollection)new int[] { }).Should().Be(string.Join("_,_", new string[0])); + ZString.Join("_,_", (ICollection)new[] { 1 }).Should().Be(string.Join("_,_", new[] { 1 })); + ZString.Join("_,_", (ICollection)new[] { 1, 2 }).Should().Be(string.Join("_,_", new[] { 1, 2 })); + ZString.Join("_,_", (ICollection)new[] { 1, 2, 3 }).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); + + ZString.Join("_,_", (IReadOnlyCollection)new int[] { }).Should().Be(string.Join("_,_", new string[0])); + ZString.Join("_,_", (IReadOnlyCollection)new[] { 1 }).Should().Be(string.Join("_,_", new[] { 1 })); + ZString.Join("_,_", (IReadOnlyCollection)new[] { 1, 2 }).Should().Be(string.Join("_,_", new[] { 1, 2 })); + ZString.Join("_,_", (IReadOnlyCollection)new[] { 1, 2, 3 }).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); + } } } From fda4928cfd41baeb33eb478e01652ce9ae94c020 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 30 Mar 2020 23:46:34 +0900 Subject: [PATCH 037/139] doc --- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 8 +++++ .../Assets/Scripts/ZString/ZString.Prepare.cs | 32 +++++++++++++++++++ .../Scripts/ZString/ZString.Utf8Format.cs | 16 ++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 12a18b65..3c664f4b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -207,6 +207,14 @@ public void AppendLine(T value) // Output + /// Copy inner buffer to the bufferWriter. + public void CopyTo(IBufferWriter bufferWriter) + { + var destination = bufferWriter.GetSpan(index); + TryCopyTo(destination, out var written); + bufferWriter.Advance(written); + } + /// Copy inner buffer to the destination span. public bool TryCopyTo(Span destination, out int bytesWritten) { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs index 9d726f64..90a309aa 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs @@ -4,161 +4,193 @@ namespace Cysharp.Text { public static partial class ZString { + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat PrepareUtf16(string format) { return new Utf16PreparedFormat(format); } + /// Prepare string format to avoid parse template in each operation. public static Utf8PreparedFormat PrepareUtf8(string format) { return new Utf8PreparedFormat(format); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs index c2fc77be..dcf7f395 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs @@ -6,6 +6,7 @@ namespace Cysharp.Text { public static partial class ZString { + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1) { var copyFrom = 0; @@ -95,6 +96,7 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2) { var copyFrom = 0; @@ -199,6 +201,7 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3) { var copyFrom = 0; @@ -318,6 +321,7 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { var copyFrom = 0; @@ -452,6 +456,7 @@ public static void Utf8Format(IBufferWriter bufferWriter, } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { var copyFrom = 0; @@ -601,6 +606,7 @@ public static void Utf8Format(IBufferWriter bufferWrit } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { var copyFrom = 0; @@ -765,6 +771,7 @@ public static void Utf8Format(IBufferWriter buffer } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { var copyFrom = 0; @@ -944,6 +951,7 @@ public static void Utf8Format(IBufferWriter bu } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { var copyFrom = 0; @@ -1138,6 +1146,7 @@ public static void Utf8Format(IBufferWriterReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { var copyFrom = 0; @@ -1347,6 +1356,7 @@ public static void Utf8Format(IBufferWriter< } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { var copyFrom = 0; @@ -1571,6 +1581,7 @@ public static void Utf8Format(IBufferWr } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { var copyFrom = 0; @@ -1810,6 +1821,7 @@ public static void Utf8Format(IBuf } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { var copyFrom = 0; @@ -2064,6 +2076,7 @@ public static void Utf8Format } } + /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { var copyFrom = 0; @@ -2333,6 +2346,7 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { var copyFrom = 0; @@ -2617,6 +2631,7 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { var copyFrom = 0; @@ -2916,6 +2931,7 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { var copyFrom = 0; From f904ddd2672db6455716458ef52f42e93c497cf3 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 30 Mar 2020 23:53:18 +0900 Subject: [PATCH 038/139] fix #7 --- .../Assets/Scripts/ZString/ZString.Concat.cs | 680 ++++++++++++++---- src/ZString/ZString.Concat.cs | 680 ++++++++++++++---- src/ZString/ZString.Concat.tt | 5 +- tests/ZString.Tests/JoinTest.cs | 7 + 4 files changed, 1099 insertions(+), 273 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs index 4c20ec55..2ab15f67 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs @@ -12,7 +12,10 @@ public static string Concat(T1 arg1) { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -39,7 +42,10 @@ public static string Concat(T1 arg1, T2 arg2) { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -52,7 +58,10 @@ public static string Concat(T1 arg1, T2 arg2) if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -79,7 +88,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3) { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -92,7 +104,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3) if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -105,7 +120,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3) if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -132,7 +150,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -145,7 +166,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -158,7 +182,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -171,7 +198,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -198,7 +228,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -211,7 +244,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -224,7 +260,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -237,7 +276,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -250,7 +292,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -277,7 +322,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -290,7 +338,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -303,7 +354,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -316,7 +370,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -329,7 +386,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -342,7 +402,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -369,7 +432,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -382,7 +448,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -395,7 +464,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -408,7 +480,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -421,7 +496,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -434,7 +512,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -447,7 +528,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -474,7 +558,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -487,7 +574,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -500,7 +590,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -513,7 +606,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -526,7 +622,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -539,7 +638,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -552,7 +654,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -565,7 +670,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -592,7 +700,10 @@ public static string Concat(T1 arg1, T2 arg2 { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -605,7 +716,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -618,7 +732,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -631,7 +748,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -644,7 +764,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -657,7 +780,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -670,7 +796,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -683,7 +812,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -696,7 +828,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T9) == typeof(string)) { - sb.Append(Unsafe.As(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -723,7 +858,10 @@ public static string Concat(T1 arg1, T2 { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -736,7 +874,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -749,7 +890,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -762,7 +906,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -775,7 +922,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -788,7 +938,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -801,7 +954,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -814,7 +970,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -827,7 +986,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T9) == typeof(string)) { - sb.Append(Unsafe.As(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -840,7 +1002,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T10) == typeof(string)) { - sb.Append(Unsafe.As(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -867,7 +1032,10 @@ public static string Concat(T1 arg { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -880,7 +1048,10 @@ public static string Concat(T1 arg if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -893,7 +1064,10 @@ public static string Concat(T1 arg if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -906,7 +1080,10 @@ public static string Concat(T1 arg if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -919,7 +1096,10 @@ public static string Concat(T1 arg if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -932,7 +1112,10 @@ public static string Concat(T1 arg if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -945,7 +1128,10 @@ public static string Concat(T1 arg if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -958,7 +1144,10 @@ public static string Concat(T1 arg if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -971,7 +1160,10 @@ public static string Concat(T1 arg if (typeof(T9) == typeof(string)) { - sb.Append(Unsafe.As(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -984,7 +1176,10 @@ public static string Concat(T1 arg if (typeof(T10) == typeof(string)) { - sb.Append(Unsafe.As(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -997,7 +1192,10 @@ public static string Concat(T1 arg if (typeof(T11) == typeof(string)) { - sb.Append(Unsafe.As(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1024,7 +1222,10 @@ public static string Concat(T { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1037,7 +1238,10 @@ public static string Concat(T if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1050,7 +1254,10 @@ public static string Concat(T if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1063,7 +1270,10 @@ public static string Concat(T if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1076,7 +1286,10 @@ public static string Concat(T if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1089,7 +1302,10 @@ public static string Concat(T if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1102,7 +1318,10 @@ public static string Concat(T if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1115,7 +1334,10 @@ public static string Concat(T if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1128,7 +1350,10 @@ public static string Concat(T if (typeof(T9) == typeof(string)) { - sb.Append(Unsafe.As(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1141,7 +1366,10 @@ public static string Concat(T if (typeof(T10) == typeof(string)) { - sb.Append(Unsafe.As(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1154,7 +1382,10 @@ public static string Concat(T if (typeof(T11) == typeof(string)) { - sb.Append(Unsafe.As(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1167,7 +1398,10 @@ public static string Concat(T if (typeof(T12) == typeof(string)) { - sb.Append(Unsafe.As(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1194,7 +1428,10 @@ public static string Concat(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1207,7 +1444,10 @@ public static string Concat(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1220,7 +1460,10 @@ public static string Concat(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1233,7 +1476,10 @@ public static string Concat(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1246,7 +1492,10 @@ public static string Concat(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1259,7 +1508,10 @@ public static string Concat(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1272,7 +1524,10 @@ public static string Concat(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1285,7 +1540,10 @@ public static string Concat(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1298,7 +1556,10 @@ public static string Concat(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1311,7 +1572,10 @@ public static string Concat(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1324,7 +1588,10 @@ public static string Concat(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1337,7 +1604,10 @@ public static string Concat(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1350,7 +1620,10 @@ public static string Concat(ref arg13)); + if(arg13 != null) + { + sb.Append(Unsafe.As(ref arg13)); + } } else if (typeof(T13) == typeof(int)) { @@ -1377,7 +1650,10 @@ public static string Concat(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1390,7 +1666,10 @@ public static string Concat(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1403,7 +1682,10 @@ public static string Concat(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1416,7 +1698,10 @@ public static string Concat(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1429,7 +1714,10 @@ public static string Concat(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1442,7 +1730,10 @@ public static string Concat(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1455,7 +1746,10 @@ public static string Concat(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1468,7 +1762,10 @@ public static string Concat(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1481,7 +1778,10 @@ public static string Concat(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1494,7 +1794,10 @@ public static string Concat(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1507,7 +1810,10 @@ public static string Concat(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1520,7 +1826,10 @@ public static string Concat(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1533,7 +1842,10 @@ public static string Concat(ref arg13)); + if(arg13 != null) + { + sb.Append(Unsafe.As(ref arg13)); + } } else if (typeof(T13) == typeof(int)) { @@ -1546,7 +1858,10 @@ public static string Concat(ref arg14)); + if(arg14 != null) + { + sb.Append(Unsafe.As(ref arg14)); + } } else if (typeof(T14) == typeof(int)) { @@ -1573,7 +1888,10 @@ public static string Concat(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1586,7 +1904,10 @@ public static string Concat(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1599,7 +1920,10 @@ public static string Concat(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1612,7 +1936,10 @@ public static string Concat(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1625,7 +1952,10 @@ public static string Concat(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1638,7 +1968,10 @@ public static string Concat(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1651,7 +1984,10 @@ public static string Concat(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1664,7 +2000,10 @@ public static string Concat(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1677,7 +2016,10 @@ public static string Concat(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1690,7 +2032,10 @@ public static string Concat(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1703,7 +2048,10 @@ public static string Concat(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1716,7 +2064,10 @@ public static string Concat(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1729,7 +2080,10 @@ public static string Concat(ref arg13)); + if(arg13 != null) + { + sb.Append(Unsafe.As(ref arg13)); + } } else if (typeof(T13) == typeof(int)) { @@ -1742,7 +2096,10 @@ public static string Concat(ref arg14)); + if(arg14 != null) + { + sb.Append(Unsafe.As(ref arg14)); + } } else if (typeof(T14) == typeof(int)) { @@ -1755,7 +2112,10 @@ public static string Concat(ref arg15)); + if(arg15 != null) + { + sb.Append(Unsafe.As(ref arg15)); + } } else if (typeof(T15) == typeof(int)) { @@ -1782,7 +2142,10 @@ public static string Concat(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1795,7 +2158,10 @@ public static string Concat(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1808,7 +2174,10 @@ public static string Concat(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1821,7 +2190,10 @@ public static string Concat(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1834,7 +2206,10 @@ public static string Concat(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1847,7 +2222,10 @@ public static string Concat(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1860,7 +2238,10 @@ public static string Concat(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1873,7 +2254,10 @@ public static string Concat(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1886,7 +2270,10 @@ public static string Concat(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1899,7 +2286,10 @@ public static string Concat(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1912,7 +2302,10 @@ public static string Concat(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1925,7 +2318,10 @@ public static string Concat(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1938,7 +2334,10 @@ public static string Concat(ref arg13)); + if(arg13 != null) + { + sb.Append(Unsafe.As(ref arg13)); + } } else if (typeof(T13) == typeof(int)) { @@ -1951,7 +2350,10 @@ public static string Concat(ref arg14)); + if(arg14 != null) + { + sb.Append(Unsafe.As(ref arg14)); + } } else if (typeof(T14) == typeof(int)) { @@ -1964,7 +2366,10 @@ public static string Concat(ref arg15)); + if(arg15 != null) + { + sb.Append(Unsafe.As(ref arg15)); + } } else if (typeof(T15) == typeof(int)) { @@ -1977,7 +2382,10 @@ public static string Concat(ref arg16)); + if(arg16 != null) + { + sb.Append(Unsafe.As(ref arg16)); + } } else if (typeof(T16) == typeof(int)) { diff --git a/src/ZString/ZString.Concat.cs b/src/ZString/ZString.Concat.cs index 4c20ec55..2ab15f67 100644 --- a/src/ZString/ZString.Concat.cs +++ b/src/ZString/ZString.Concat.cs @@ -12,7 +12,10 @@ public static string Concat(T1 arg1) { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -39,7 +42,10 @@ public static string Concat(T1 arg1, T2 arg2) { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -52,7 +58,10 @@ public static string Concat(T1 arg1, T2 arg2) if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -79,7 +88,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3) { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -92,7 +104,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3) if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -105,7 +120,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3) if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -132,7 +150,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -145,7 +166,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -158,7 +182,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -171,7 +198,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 arg4) if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -198,7 +228,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -211,7 +244,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -224,7 +260,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -237,7 +276,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -250,7 +292,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T4 ar if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -277,7 +322,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -290,7 +338,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -303,7 +354,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -316,7 +370,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -329,7 +386,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -342,7 +402,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg3, T if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -369,7 +432,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -382,7 +448,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -395,7 +464,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -408,7 +480,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -421,7 +496,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -434,7 +512,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -447,7 +528,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 arg if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -474,7 +558,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -487,7 +574,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -500,7 +590,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -513,7 +606,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -526,7 +622,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -539,7 +638,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -552,7 +654,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -565,7 +670,10 @@ public static string Concat(T1 arg1, T2 arg2, T3 if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -592,7 +700,10 @@ public static string Concat(T1 arg1, T2 arg2 { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -605,7 +716,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -618,7 +732,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -631,7 +748,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -644,7 +764,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -657,7 +780,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -670,7 +796,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -683,7 +812,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -696,7 +828,10 @@ public static string Concat(T1 arg1, T2 arg2 if (typeof(T9) == typeof(string)) { - sb.Append(Unsafe.As(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -723,7 +858,10 @@ public static string Concat(T1 arg1, T2 { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -736,7 +874,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -749,7 +890,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -762,7 +906,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -775,7 +922,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -788,7 +938,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -801,7 +954,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -814,7 +970,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -827,7 +986,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T9) == typeof(string)) { - sb.Append(Unsafe.As(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -840,7 +1002,10 @@ public static string Concat(T1 arg1, T2 if (typeof(T10) == typeof(string)) { - sb.Append(Unsafe.As(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -867,7 +1032,10 @@ public static string Concat(T1 arg { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -880,7 +1048,10 @@ public static string Concat(T1 arg if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -893,7 +1064,10 @@ public static string Concat(T1 arg if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -906,7 +1080,10 @@ public static string Concat(T1 arg if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -919,7 +1096,10 @@ public static string Concat(T1 arg if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -932,7 +1112,10 @@ public static string Concat(T1 arg if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -945,7 +1128,10 @@ public static string Concat(T1 arg if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -958,7 +1144,10 @@ public static string Concat(T1 arg if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -971,7 +1160,10 @@ public static string Concat(T1 arg if (typeof(T9) == typeof(string)) { - sb.Append(Unsafe.As(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -984,7 +1176,10 @@ public static string Concat(T1 arg if (typeof(T10) == typeof(string)) { - sb.Append(Unsafe.As(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -997,7 +1192,10 @@ public static string Concat(T1 arg if (typeof(T11) == typeof(string)) { - sb.Append(Unsafe.As(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1024,7 +1222,10 @@ public static string Concat(T { if (typeof(T1) == typeof(string)) { - sb.Append(Unsafe.As(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1037,7 +1238,10 @@ public static string Concat(T if (typeof(T2) == typeof(string)) { - sb.Append(Unsafe.As(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1050,7 +1254,10 @@ public static string Concat(T if (typeof(T3) == typeof(string)) { - sb.Append(Unsafe.As(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1063,7 +1270,10 @@ public static string Concat(T if (typeof(T4) == typeof(string)) { - sb.Append(Unsafe.As(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1076,7 +1286,10 @@ public static string Concat(T if (typeof(T5) == typeof(string)) { - sb.Append(Unsafe.As(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1089,7 +1302,10 @@ public static string Concat(T if (typeof(T6) == typeof(string)) { - sb.Append(Unsafe.As(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1102,7 +1318,10 @@ public static string Concat(T if (typeof(T7) == typeof(string)) { - sb.Append(Unsafe.As(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1115,7 +1334,10 @@ public static string Concat(T if (typeof(T8) == typeof(string)) { - sb.Append(Unsafe.As(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1128,7 +1350,10 @@ public static string Concat(T if (typeof(T9) == typeof(string)) { - sb.Append(Unsafe.As(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1141,7 +1366,10 @@ public static string Concat(T if (typeof(T10) == typeof(string)) { - sb.Append(Unsafe.As(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1154,7 +1382,10 @@ public static string Concat(T if (typeof(T11) == typeof(string)) { - sb.Append(Unsafe.As(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1167,7 +1398,10 @@ public static string Concat(T if (typeof(T12) == typeof(string)) { - sb.Append(Unsafe.As(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1194,7 +1428,10 @@ public static string Concat(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1207,7 +1444,10 @@ public static string Concat(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1220,7 +1460,10 @@ public static string Concat(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1233,7 +1476,10 @@ public static string Concat(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1246,7 +1492,10 @@ public static string Concat(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1259,7 +1508,10 @@ public static string Concat(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1272,7 +1524,10 @@ public static string Concat(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1285,7 +1540,10 @@ public static string Concat(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1298,7 +1556,10 @@ public static string Concat(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1311,7 +1572,10 @@ public static string Concat(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1324,7 +1588,10 @@ public static string Concat(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1337,7 +1604,10 @@ public static string Concat(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1350,7 +1620,10 @@ public static string Concat(ref arg13)); + if(arg13 != null) + { + sb.Append(Unsafe.As(ref arg13)); + } } else if (typeof(T13) == typeof(int)) { @@ -1377,7 +1650,10 @@ public static string Concat(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1390,7 +1666,10 @@ public static string Concat(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1403,7 +1682,10 @@ public static string Concat(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1416,7 +1698,10 @@ public static string Concat(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1429,7 +1714,10 @@ public static string Concat(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1442,7 +1730,10 @@ public static string Concat(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1455,7 +1746,10 @@ public static string Concat(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1468,7 +1762,10 @@ public static string Concat(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1481,7 +1778,10 @@ public static string Concat(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1494,7 +1794,10 @@ public static string Concat(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1507,7 +1810,10 @@ public static string Concat(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1520,7 +1826,10 @@ public static string Concat(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1533,7 +1842,10 @@ public static string Concat(ref arg13)); + if(arg13 != null) + { + sb.Append(Unsafe.As(ref arg13)); + } } else if (typeof(T13) == typeof(int)) { @@ -1546,7 +1858,10 @@ public static string Concat(ref arg14)); + if(arg14 != null) + { + sb.Append(Unsafe.As(ref arg14)); + } } else if (typeof(T14) == typeof(int)) { @@ -1573,7 +1888,10 @@ public static string Concat(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1586,7 +1904,10 @@ public static string Concat(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1599,7 +1920,10 @@ public static string Concat(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1612,7 +1936,10 @@ public static string Concat(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1625,7 +1952,10 @@ public static string Concat(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1638,7 +1968,10 @@ public static string Concat(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1651,7 +1984,10 @@ public static string Concat(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1664,7 +2000,10 @@ public static string Concat(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1677,7 +2016,10 @@ public static string Concat(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1690,7 +2032,10 @@ public static string Concat(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1703,7 +2048,10 @@ public static string Concat(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1716,7 +2064,10 @@ public static string Concat(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1729,7 +2080,10 @@ public static string Concat(ref arg13)); + if(arg13 != null) + { + sb.Append(Unsafe.As(ref arg13)); + } } else if (typeof(T13) == typeof(int)) { @@ -1742,7 +2096,10 @@ public static string Concat(ref arg14)); + if(arg14 != null) + { + sb.Append(Unsafe.As(ref arg14)); + } } else if (typeof(T14) == typeof(int)) { @@ -1755,7 +2112,10 @@ public static string Concat(ref arg15)); + if(arg15 != null) + { + sb.Append(Unsafe.As(ref arg15)); + } } else if (typeof(T15) == typeof(int)) { @@ -1782,7 +2142,10 @@ public static string Concat(ref arg1)); + if(arg1 != null) + { + sb.Append(Unsafe.As(ref arg1)); + } } else if (typeof(T1) == typeof(int)) { @@ -1795,7 +2158,10 @@ public static string Concat(ref arg2)); + if(arg2 != null) + { + sb.Append(Unsafe.As(ref arg2)); + } } else if (typeof(T2) == typeof(int)) { @@ -1808,7 +2174,10 @@ public static string Concat(ref arg3)); + if(arg3 != null) + { + sb.Append(Unsafe.As(ref arg3)); + } } else if (typeof(T3) == typeof(int)) { @@ -1821,7 +2190,10 @@ public static string Concat(ref arg4)); + if(arg4 != null) + { + sb.Append(Unsafe.As(ref arg4)); + } } else if (typeof(T4) == typeof(int)) { @@ -1834,7 +2206,10 @@ public static string Concat(ref arg5)); + if(arg5 != null) + { + sb.Append(Unsafe.As(ref arg5)); + } } else if (typeof(T5) == typeof(int)) { @@ -1847,7 +2222,10 @@ public static string Concat(ref arg6)); + if(arg6 != null) + { + sb.Append(Unsafe.As(ref arg6)); + } } else if (typeof(T6) == typeof(int)) { @@ -1860,7 +2238,10 @@ public static string Concat(ref arg7)); + if(arg7 != null) + { + sb.Append(Unsafe.As(ref arg7)); + } } else if (typeof(T7) == typeof(int)) { @@ -1873,7 +2254,10 @@ public static string Concat(ref arg8)); + if(arg8 != null) + { + sb.Append(Unsafe.As(ref arg8)); + } } else if (typeof(T8) == typeof(int)) { @@ -1886,7 +2270,10 @@ public static string Concat(ref arg9)); + if(arg9 != null) + { + sb.Append(Unsafe.As(ref arg9)); + } } else if (typeof(T9) == typeof(int)) { @@ -1899,7 +2286,10 @@ public static string Concat(ref arg10)); + if(arg10 != null) + { + sb.Append(Unsafe.As(ref arg10)); + } } else if (typeof(T10) == typeof(int)) { @@ -1912,7 +2302,10 @@ public static string Concat(ref arg11)); + if(arg11 != null) + { + sb.Append(Unsafe.As(ref arg11)); + } } else if (typeof(T11) == typeof(int)) { @@ -1925,7 +2318,10 @@ public static string Concat(ref arg12)); + if(arg12 != null) + { + sb.Append(Unsafe.As(ref arg12)); + } } else if (typeof(T12) == typeof(int)) { @@ -1938,7 +2334,10 @@ public static string Concat(ref arg13)); + if(arg13 != null) + { + sb.Append(Unsafe.As(ref arg13)); + } } else if (typeof(T13) == typeof(int)) { @@ -1951,7 +2350,10 @@ public static string Concat(ref arg14)); + if(arg14 != null) + { + sb.Append(Unsafe.As(ref arg14)); + } } else if (typeof(T14) == typeof(int)) { @@ -1964,7 +2366,10 @@ public static string Concat(ref arg15)); + if(arg15 != null) + { + sb.Append(Unsafe.As(ref arg15)); + } } else if (typeof(T15) == typeof(int)) { @@ -1977,7 +2382,10 @@ public static string Concat(ref arg16)); + if(arg16 != null) + { + sb.Append(Unsafe.As(ref arg16)); + } } else if (typeof(T16) == typeof(int)) { diff --git a/src/ZString/ZString.Concat.tt b/src/ZString/ZString.Concat.tt index 664d0207..aac7d159 100644 --- a/src/ZString/ZString.Concat.tt +++ b/src/ZString/ZString.Concat.tt @@ -32,7 +32,10 @@ namespace Cysharp.Text <# for(var j = 0; j < i; j++) { #> if (typeof(T<#= j + 1 #>) == typeof(string)) { - sb.Append(Unsafe.As, string>(ref arg<#= j + 1 #>)); + if(arg<#= j + 1 #> != null) + { + sb.Append(Unsafe.As, string>(ref arg<#= j + 1 #>)); + } } else if (typeof(T<#= j + 1 #>) == typeof(int)) { diff --git a/tests/ZString.Tests/JoinTest.cs b/tests/ZString.Tests/JoinTest.cs index 8f1b9cfb..b3251f4b 100644 --- a/tests/ZString.Tests/JoinTest.cs +++ b/tests/ZString.Tests/JoinTest.cs @@ -62,5 +62,12 @@ public void JoinOverloads2() ZString.Join("_,_", (IReadOnlyCollection)new[] { 1, 2 }).Should().Be(string.Join("_,_", new[] { 1, 2 })); ZString.Join("_,_", (IReadOnlyCollection)new[] { 1, 2, 3 }).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); } + + [Fact] + public void CooncatNullTest() + { + var str = ZString.Concat(default(string), "foo", "bar"); + str.Should().Be(string.Concat(default(string), "foo", "bar")); + } } } From 83cd9907d29e34a14728c6a49a684767ba339f1e Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 31 Mar 2020 00:01:01 +0900 Subject: [PATCH 039/139] run --- .../Assets/Scripts/ZString/ExceptionUtil.cs | 19 +++ .../Scripts/ZString/ExceptionUtil.cs.meta | 11 ++ .../Scripts/ZString/PreparedFormat.cs.meta | 11 ++ .../Scripts/ZString/PreparedFormatHelper.cs | 109 ++++++++++++++++++ .../ZString/PreparedFormatHelper.cs.meta | 11 ++ .../Scripts/ZString/ZString.Prepare.cs.meta | 11 ++ .../ZString/ZString.Utf8Format.cs.meta | 11 ++ src/ZString/ZString.csproj | 60 +++++----- tests/ZString.Tests/FormatTest.cs | 2 +- 9 files changed, 213 insertions(+), 32 deletions(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs.meta diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs b/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs new file mode 100644 index 00000000..64413691 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + internal static class ExceptionUtil + { + internal static void ThrowArgumentException(string paramName) + { + throw new ArgumentException("Can't format argument.", paramName); + } + + internal static void ThrowFormatException() + { + throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs.meta new file mode 100644 index 00000000..72aeb775 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c69ccd87e4d4ef74eaf019d0603195e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs.meta new file mode 100644 index 00000000..9ee42407 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b2d2a7b702a661244a4045fcf67fe6ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs new file mode 100644 index 00000000..60bdcfd9 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs @@ -0,0 +1,109 @@ +using System; +using System.Buffers; +using System.Collections.Generic; + +namespace Cysharp.Text +{ + internal static class PreparedFormatHelper + { + internal static FormatSegment[] Parse(string format, bool withStandardFormat) + { + var list = new List(); + + var copyFrom = 0; + for (int i = 0; i < format.Length; i++) + { + if (format[i] == '{') + { + // escape. + if (i == format.Length - 1) + { + throw new FormatException("invalid format"); + } + + if (i != format.Length && format[i + 1] == '{') + { + var size = i - copyFrom; + if (size != 0) + { + list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); + } + i = i + 1; // skip escaped '{' + copyFrom = i; + continue; + } + else + { + var size = i - copyFrom; + if (size != 0) + { + list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); + } + } + + // try to find range + var indexParse = FormatParser.Parse(format.AsSpan(i)); + list.Add(new FormatSegment(0, 0, true, indexParse.Index, indexParse.FormatString.ToString(), withStandardFormat)); + + copyFrom = i + indexParse.LastIndex + 1; + i = i + indexParse.LastIndex; + } + else if (format[i] == '}') + { + if (i != format.Length && format[i + 1] == '}') + { + var size = i - copyFrom; + if (size != 0) + { + list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); + } + i = i + 1; // skip escaped '}' + copyFrom = i; + continue; + } + } + } + + { + // final string + var copyLength = format.Length - copyFrom; + if (copyLength > 0) + { + list.Add(new FormatSegment(copyFrom, copyLength, false, 0, null, withStandardFormat)); + } + } + + return list.ToArray(); + } + } + + + internal readonly struct FormatSegment + { + public readonly int Offset; + public readonly int Count; + public readonly bool IsFormatArgument; + public readonly int FormatIndex; + public readonly string FormatString; + + // Utf8 + public readonly StandardFormat StandardFormat; + + public FormatSegment(int offset, int count, bool isFormatArgument, int formatIndex, string formatString, bool utf8) + { + Offset = offset; + Count = count; + IsFormatArgument = isFormatArgument; + FormatIndex = formatIndex; + FormatString = formatString; + if (utf8) + { + StandardFormat = (formatString != null) ? StandardFormat.Parse(formatString) : default; + } + else + { + StandardFormat = default; + } + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs.meta new file mode 100644 index 00000000..ecf22f56 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 97f2a4c405b87a245ac38c1755f74a3b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs.meta new file mode 100644 index 00000000..cc2e36c5 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Prepare.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fca154d819b770049860ac2c8c621141 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs.meta new file mode 100644 index 00000000..48600d47 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdd4edf33de6a6c4b9911c8f3515cb8d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index 46ef491a..a9ce33aa 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -32,8 +32,8 @@ - TextTemplatingFileGenerator - PreparedFormat.cs + TextTemplatingFileGenerator + PreparedFormat.cs TextTemplatingFileGenerator @@ -80,20 +80,20 @@ ZString.Format.cs - TextTemplatingFileGenerator - ZString.Prepare.cs + TextTemplatingFileGenerator + ZString.Prepare.cs - TextTemplatingFileGenerator - ZString.Utf8Format.cs + TextTemplatingFileGenerator + ZString.Utf8Format.cs - True - True - PreparedFormat.tt + True + True + PreparedFormat.tt True @@ -146,15 +146,29 @@ ZString.Format.tt - True - True - ZString.Prepare.tt + True + True + ZString.Prepare.tt - True - True - ZString.Utf8Format.tt + True + True + ZString.Utf8Format.tt + + + + + + True + True + PreparedFormat.tt + + + True + True + ZString.Utf8Format.tt + @@ -168,22 +182,6 @@ - - - - - - - True - True - PreparedFormat.tt - - - True - True - ZString.Utf8Format.tt - - diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index 2c76cbbb..67a5da15 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -39,7 +39,7 @@ void Test(string format, T0 t0, T1 t1) // Direct { -#if !NETCOREAPP2_1 +#if NETCOREAPP3_1 var writer = new ArrayBufferWriter(); ZString.Utf8Format(writer, format, t0, t1); var actual = Encoding.UTF8.GetString(writer.WrittenSpan); From 642182aa3829dc608201ab250565d02f154a7849 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 31 Mar 2020 00:03:12 +0900 Subject: [PATCH 040/139] CI --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 31fb96f2..1f514747 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -119,6 +119,7 @@ workflows: only: /^\d\.\d\.\d.*/ branches: ignore: /.*/ + context: cysharp-nuget - upload-github: requires: - build-unity From 80bc1e989a1e565476929a2c7bcc724269f051b8 Mon Sep 17 00:00:00 2001 From: Kawai Yoshifumi Date: Fri, 3 Apr 2020 12:12:56 +0900 Subject: [PATCH 041/139] fix resize buffer issue(append large string). --- sandbox/ConsoleApp/Program.cs | 15 ++--- .../ZString/IResettableBufferWriter.cs | 12 ++++ ...alueStringBuilder.SpanFormattableAppend.cs | 60 +++++++++---------- .../ZString/Utf16ValueStringBuilder.cs | 13 +++- ...alueStringBuilder.SpanFormattableAppend.cs | 60 +++++++++---------- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 11 +++- .../Assets/Scripts/ZString/ZString.cs | 14 ++--- src/ZString/IResettableBufferWriter.cs | 12 ++++ ...alueStringBuilder.SpanFormattableAppend.cs | 60 +++++++++---------- ...alueStringBuilder.SpanFormattableAppend.tt | 4 +- src/ZString/Utf16ValueStringBuilder.cs | 13 +++- ...alueStringBuilder.SpanFormattableAppend.cs | 60 +++++++++---------- ...alueStringBuilder.SpanFormattableAppend.tt | 4 +- src/ZString/Utf8ValueStringBuilder.cs | 11 +++- src/ZString/ZString.cs | 14 ++--- tests/ZString.Tests/JoinTest.cs | 11 ++++ 16 files changed, 217 insertions(+), 157 deletions(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/IResettableBufferWriter.cs create mode 100644 src/ZString/IResettableBufferWriter.cs diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index 49ad4fe2..e7634073 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -1,10 +1,13 @@ using Cysharp.Text; using System; using System.Buffers; +using System.Collections.Concurrent; using System.Linq; using System.Text; using System.Text.Formatting; using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; namespace ConsoleApp { @@ -22,15 +25,13 @@ static void Main(string[] args) static void Run() { - using var sb = ZString.CreateUtf8StringBuilder(); - IBufferWriter boxed = sb; - var writer = new Utf8JsonWriter(boxed); - JsonSerializer.Serialize(writer, new { foo = 999 }); +var a = new string('a', 10000); +var b = new string('b', 1000000); - using var unboxed = (Utf8ValueStringBuilder)boxed; +ZString.Join(',', new string[] { a, b }); + + - Console.WriteLine(sb.ToString()); - Console.WriteLine(unboxed.ToString()); } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/IResettableBufferWriter.cs b/src/ZString.Unity/Assets/Scripts/ZString/IResettableBufferWriter.cs new file mode 100644 index 00000000..bcdb1524 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/IResettableBufferWriter.cs @@ -0,0 +1,12 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + public interface IResettableBufferWriter : IBufferWriter + { + void Reset(); + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index 29a6d10c..0f07d69a 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -11,7 +11,7 @@ public void Append(System.Byte value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -26,7 +26,7 @@ public void Append(System.Byte value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -56,7 +56,7 @@ public void Append(System.DateTime value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -71,7 +71,7 @@ public void Append(System.DateTime value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -101,7 +101,7 @@ public void Append(System.DateTimeOffset value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -116,7 +116,7 @@ public void Append(System.DateTimeOffset value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -146,7 +146,7 @@ public void Append(System.Decimal value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -161,7 +161,7 @@ public void Append(System.Decimal value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -191,7 +191,7 @@ public void Append(System.Double value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -206,7 +206,7 @@ public void Append(System.Double value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -236,7 +236,7 @@ public void Append(System.Int16 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -251,7 +251,7 @@ public void Append(System.Int16 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -281,7 +281,7 @@ public void Append(System.Int32 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -296,7 +296,7 @@ public void Append(System.Int32 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -326,7 +326,7 @@ public void Append(System.Int64 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -341,7 +341,7 @@ public void Append(System.Int64 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -371,7 +371,7 @@ public void Append(System.SByte value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -386,7 +386,7 @@ public void Append(System.SByte value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -416,7 +416,7 @@ public void Append(System.Single value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -431,7 +431,7 @@ public void Append(System.Single value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -461,7 +461,7 @@ public void Append(System.TimeSpan value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -476,7 +476,7 @@ public void Append(System.TimeSpan value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -506,7 +506,7 @@ public void Append(System.UInt16 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -521,7 +521,7 @@ public void Append(System.UInt16 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -551,7 +551,7 @@ public void Append(System.UInt32 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -566,7 +566,7 @@ public void Append(System.UInt32 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -596,7 +596,7 @@ public void Append(System.UInt64 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -611,7 +611,7 @@ public void Append(System.UInt64 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -641,7 +641,7 @@ public void Append(System.Guid value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -656,7 +656,7 @@ public void Append(System.Guid value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 954e2f17..76809a18 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -1,10 +1,11 @@ using System; using System.Buffers; +using System.IO; using System.Runtime.CompilerServices; namespace Cysharp.Text { - public partial struct Utf16ValueStringBuilder : IDisposable, IBufferWriter + public partial struct Utf16ValueStringBuilder : IDisposable, IBufferWriter, IResettableBufferWriter { public delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); @@ -88,13 +89,14 @@ public void Dispose() public void TryGrow(int sizeHint) { + if (buffer.Length < index + sizeHint) { Grow(sizeHint); } } - public void Grow(int sizeHint = 0) + public void Grow(int sizeHint) { var nextSize = buffer.Length * 2; if (sizeHint != 0) @@ -178,7 +180,7 @@ public void Append(T value) { if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) { ThrowArgumentException(nameof(value)); @@ -246,6 +248,11 @@ public void Advance(int count) index += count; } + void IResettableBufferWriter.Reset() + { + index = 0; + } + void ThrowArgumentException(string paramName) { throw new ArgumentException("Can't format argument.", paramName); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index ecfef55d..09b1c062 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -13,7 +13,7 @@ public void Append(System.Byte value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -28,7 +28,7 @@ public void Append(System.Byte value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -58,7 +58,7 @@ public void Append(System.DateTime value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -73,7 +73,7 @@ public void Append(System.DateTime value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -103,7 +103,7 @@ public void Append(System.DateTimeOffset value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -118,7 +118,7 @@ public void Append(System.DateTimeOffset value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -148,7 +148,7 @@ public void Append(System.Decimal value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -163,7 +163,7 @@ public void Append(System.Decimal value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -193,7 +193,7 @@ public void Append(System.Double value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -208,7 +208,7 @@ public void Append(System.Double value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -238,7 +238,7 @@ public void Append(System.Int16 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -253,7 +253,7 @@ public void Append(System.Int16 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -283,7 +283,7 @@ public void Append(System.Int32 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -298,7 +298,7 @@ public void Append(System.Int32 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -328,7 +328,7 @@ public void Append(System.Int64 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -343,7 +343,7 @@ public void Append(System.Int64 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -373,7 +373,7 @@ public void Append(System.SByte value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -388,7 +388,7 @@ public void Append(System.SByte value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -418,7 +418,7 @@ public void Append(System.Single value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -433,7 +433,7 @@ public void Append(System.Single value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -463,7 +463,7 @@ public void Append(System.TimeSpan value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -478,7 +478,7 @@ public void Append(System.TimeSpan value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -508,7 +508,7 @@ public void Append(System.UInt16 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -523,7 +523,7 @@ public void Append(System.UInt16 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -553,7 +553,7 @@ public void Append(System.UInt32 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -568,7 +568,7 @@ public void Append(System.UInt32 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -598,7 +598,7 @@ public void Append(System.UInt64 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -613,7 +613,7 @@ public void Append(System.UInt64 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -643,7 +643,7 @@ public void Append(System.Guid value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -658,7 +658,7 @@ public void Append(System.Guid value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 3c664f4b..eef8142a 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -7,7 +7,7 @@ namespace Cysharp.Text { - public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter + public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter, IResettableBufferWriter { public delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); @@ -101,7 +101,7 @@ public void TryGrow(int sizeHint) } } - public void Grow(int sizeHint = 0) + public void Grow(int sizeHint) { var nextSize = buffer.Length * 2; if (sizeHint != 0) @@ -189,7 +189,7 @@ public void Append(T value) { if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) { ThrowArgumentException(nameof(value)); @@ -271,6 +271,11 @@ public void Advance(int count) index += count; } + void IResettableBufferWriter.Reset() + { + index = 0; + } + void ThrowArgumentException(string paramName) { throw new ArgumentException("Can't format argument.", paramName); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index f8ddaee2..1360efd2 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -36,7 +36,7 @@ public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, params T[] values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { for (int i = 0; i < values.Length; i++) @@ -58,7 +58,7 @@ public static string Join(char separator, params T[] values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { for (int i = 0; i < values.Length; i++) @@ -80,7 +80,7 @@ public static string Join(char separator, ReadOnlySpan values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, IEnumerable values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { var isFirst = true; @@ -108,7 +108,7 @@ public static string Join(char separator, IEnumerable values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { for (int i = 0; i < values.Length; i++) @@ -130,7 +130,7 @@ public static string Join(string separator, params T[] values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, List values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { var count = values.Count; @@ -153,7 +153,7 @@ public static string Join(string separator, List values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, ReadOnlySpan values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { for (int i = 0; i < values.Length; i++) @@ -195,7 +195,7 @@ public static string Join(string separator, IReadOnlyCollection values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, IEnumerable values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { var isFirst = true; diff --git a/src/ZString/IResettableBufferWriter.cs b/src/ZString/IResettableBufferWriter.cs new file mode 100644 index 00000000..bcdb1524 --- /dev/null +++ b/src/ZString/IResettableBufferWriter.cs @@ -0,0 +1,12 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; + +namespace Cysharp.Text +{ + public interface IResettableBufferWriter : IBufferWriter + { + void Reset(); + } +} diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index 29a6d10c..0f07d69a 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -11,7 +11,7 @@ public void Append(System.Byte value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -26,7 +26,7 @@ public void Append(System.Byte value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -56,7 +56,7 @@ public void Append(System.DateTime value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -71,7 +71,7 @@ public void Append(System.DateTime value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -101,7 +101,7 @@ public void Append(System.DateTimeOffset value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -116,7 +116,7 @@ public void Append(System.DateTimeOffset value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -146,7 +146,7 @@ public void Append(System.Decimal value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -161,7 +161,7 @@ public void Append(System.Decimal value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -191,7 +191,7 @@ public void Append(System.Double value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -206,7 +206,7 @@ public void Append(System.Double value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -236,7 +236,7 @@ public void Append(System.Int16 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -251,7 +251,7 @@ public void Append(System.Int16 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -281,7 +281,7 @@ public void Append(System.Int32 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -296,7 +296,7 @@ public void Append(System.Int32 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -326,7 +326,7 @@ public void Append(System.Int64 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -341,7 +341,7 @@ public void Append(System.Int64 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -371,7 +371,7 @@ public void Append(System.SByte value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -386,7 +386,7 @@ public void Append(System.SByte value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -416,7 +416,7 @@ public void Append(System.Single value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -431,7 +431,7 @@ public void Append(System.Single value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -461,7 +461,7 @@ public void Append(System.TimeSpan value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -476,7 +476,7 @@ public void Append(System.TimeSpan value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -506,7 +506,7 @@ public void Append(System.UInt16 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -521,7 +521,7 @@ public void Append(System.UInt16 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -551,7 +551,7 @@ public void Append(System.UInt32 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -566,7 +566,7 @@ public void Append(System.UInt32 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -596,7 +596,7 @@ public void Append(System.UInt64 value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -611,7 +611,7 @@ public void Append(System.UInt64 value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); @@ -641,7 +641,7 @@ public void Append(System.Guid value) { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -656,7 +656,7 @@ public void Append(System.Guid value, string format) { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt index 545619e6..d48abf68 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt @@ -39,7 +39,7 @@ namespace Cysharp.Text { if(!value.TryFormat(buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -54,7 +54,7 @@ namespace Cysharp.Text { if(!value.TryFormat(buffer.AsSpan(index), out var written, format.AsSpan())) { - Grow(); + Grow(written); if(!value.TryFormat(buffer.AsSpan(index), out written, format.AsSpan())) { ThrowArgumentException(nameof(value)); diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 954e2f17..76809a18 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -1,10 +1,11 @@ using System; using System.Buffers; +using System.IO; using System.Runtime.CompilerServices; namespace Cysharp.Text { - public partial struct Utf16ValueStringBuilder : IDisposable, IBufferWriter + public partial struct Utf16ValueStringBuilder : IDisposable, IBufferWriter, IResettableBufferWriter { public delegate bool TryFormat(T value, Span destination, out int charsWritten, ReadOnlySpan format); @@ -88,13 +89,14 @@ public void Dispose() public void TryGrow(int sizeHint) { + if (buffer.Length < index + sizeHint) { Grow(sizeHint); } } - public void Grow(int sizeHint = 0) + public void Grow(int sizeHint) { var nextSize = buffer.Length * 2; if (sizeHint != 0) @@ -178,7 +180,7 @@ public void Append(T value) { if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) { ThrowArgumentException(nameof(value)); @@ -246,6 +248,11 @@ public void Advance(int count) index += count; } + void IResettableBufferWriter.Reset() + { + index = 0; + } + void ThrowArgumentException(string paramName) { throw new ArgumentException("Can't format argument.", paramName); diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index ecfef55d..09b1c062 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -13,7 +13,7 @@ public void Append(System.Byte value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -28,7 +28,7 @@ public void Append(System.Byte value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -58,7 +58,7 @@ public void Append(System.DateTime value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -73,7 +73,7 @@ public void Append(System.DateTime value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -103,7 +103,7 @@ public void Append(System.DateTimeOffset value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -118,7 +118,7 @@ public void Append(System.DateTimeOffset value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -148,7 +148,7 @@ public void Append(System.Decimal value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -163,7 +163,7 @@ public void Append(System.Decimal value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -193,7 +193,7 @@ public void Append(System.Double value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -208,7 +208,7 @@ public void Append(System.Double value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -238,7 +238,7 @@ public void Append(System.Int16 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -253,7 +253,7 @@ public void Append(System.Int16 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -283,7 +283,7 @@ public void Append(System.Int32 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -298,7 +298,7 @@ public void Append(System.Int32 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -328,7 +328,7 @@ public void Append(System.Int64 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -343,7 +343,7 @@ public void Append(System.Int64 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -373,7 +373,7 @@ public void Append(System.SByte value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -388,7 +388,7 @@ public void Append(System.SByte value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -418,7 +418,7 @@ public void Append(System.Single value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -433,7 +433,7 @@ public void Append(System.Single value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -463,7 +463,7 @@ public void Append(System.TimeSpan value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -478,7 +478,7 @@ public void Append(System.TimeSpan value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -508,7 +508,7 @@ public void Append(System.UInt16 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -523,7 +523,7 @@ public void Append(System.UInt16 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -553,7 +553,7 @@ public void Append(System.UInt32 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -568,7 +568,7 @@ public void Append(System.UInt32 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -598,7 +598,7 @@ public void Append(System.UInt64 value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -613,7 +613,7 @@ public void Append(System.UInt64 value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); @@ -643,7 +643,7 @@ public void Append(System.Guid value) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -658,7 +658,7 @@ public void Append(System.Guid value, StandardFormat format) { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt index c84b7980..171af036 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt @@ -41,7 +41,7 @@ namespace Cysharp.Text { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) { ThrowArgumentException(nameof(value)); @@ -56,7 +56,7 @@ namespace Cysharp.Text { if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) { - Grow(); + Grow(written); if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) { ThrowArgumentException(nameof(value)); diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 3c664f4b..eef8142a 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -7,7 +7,7 @@ namespace Cysharp.Text { - public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter + public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter, IResettableBufferWriter { public delegate bool TryFormat(T value, Span destination, out int written, StandardFormat format); @@ -101,7 +101,7 @@ public void TryGrow(int sizeHint) } } - public void Grow(int sizeHint = 0) + public void Grow(int sizeHint) { var nextSize = buffer.Length * 2; if (sizeHint != 0) @@ -189,7 +189,7 @@ public void Append(T value) { if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out var written, default)) { - Grow(); + Grow(written); if (!FormatterCache.TryFormatDelegate(value, buffer.AsSpan(index), out written, default)) { ThrowArgumentException(nameof(value)); @@ -271,6 +271,11 @@ public void Advance(int count) index += count; } + void IResettableBufferWriter.Reset() + { + index = 0; + } + void ThrowArgumentException(string paramName) { throw new ArgumentException("Can't format argument.", paramName); diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index f8ddaee2..1360efd2 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -36,7 +36,7 @@ public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, params T[] values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { for (int i = 0; i < values.Length; i++) @@ -58,7 +58,7 @@ public static string Join(char separator, params T[] values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { for (int i = 0; i < values.Length; i++) @@ -80,7 +80,7 @@ public static string Join(char separator, ReadOnlySpan values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, IEnumerable values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { var isFirst = true; @@ -108,7 +108,7 @@ public static string Join(char separator, IEnumerable values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { for (int i = 0; i < values.Length; i++) @@ -130,7 +130,7 @@ public static string Join(string separator, params T[] values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, List values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { var count = values.Count; @@ -153,7 +153,7 @@ public static string Join(string separator, List values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, ReadOnlySpan values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { for (int i = 0; i < values.Length; i++) @@ -195,7 +195,7 @@ public static string Join(string separator, IReadOnlyCollection values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, IEnumerable values) { - var sb = new Utf8ValueStringBuilder(true); + var sb = new Utf16ValueStringBuilder(true); try { var isFirst = true; diff --git a/tests/ZString.Tests/JoinTest.cs b/tests/ZString.Tests/JoinTest.cs index b3251f4b..790831e6 100644 --- a/tests/ZString.Tests/JoinTest.cs +++ b/tests/ZString.Tests/JoinTest.cs @@ -69,5 +69,16 @@ public void CooncatNullTest() var str = ZString.Concat(default(string), "foo", "bar"); str.Should().Be(string.Concat(default(string), "foo", "bar")); } + + [Fact] + public void ConcatHugeString() + { + var a = new string('a', 10000); + var b = new string('b', 1000000); + + var actrual = ZString.Join(',', new string[] { a, b }); + var expected = string.Join(',', new string[] { a, b }); + actrual.Should().Be(expected); + } } } From 3504ad4c825a72354eaa85e57d5badd349b13331 Mon Sep 17 00:00:00 2001 From: Takaaki Suzuki Date: Sun, 5 Apr 2020 15:01:01 +0900 Subject: [PATCH 042/139] Add Join(char, XxxCollection) overloads --- .../Assets/Scripts/ZString/ZString.cs | 43 +++++++++++++++++++ src/ZString/ZString.cs | 43 +++++++++++++++++++ tests/ZString.Tests/JoinTest.cs | 29 +++++++++++++ 3 files changed, 115 insertions(+) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 1360efd2..8c02e802 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -55,6 +55,29 @@ public static string Join(char separator, params T[] values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(char separator, List values) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { @@ -105,6 +128,26 @@ public static string Join(char separator, IEnumerable values) } } + public static string Join(char separator, ICollection values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(char separator, IList values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(char separator, IReadOnlyList values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(char separator, IReadOnlyCollection values) + { + return Join(separator, values.AsEnumerable()); + } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 1360efd2..8c02e802 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -55,6 +55,29 @@ public static string Join(char separator, params T[] values) } } + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(char separator, List values) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + sb.Append(separator); + } + sb.Append(values[i]); + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { @@ -105,6 +128,26 @@ public static string Join(char separator, IEnumerable values) } } + public static string Join(char separator, ICollection values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(char separator, IList values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(char separator, IReadOnlyList values) + { + return Join(separator, values.AsEnumerable()); + } + + public static string Join(char separator, IReadOnlyCollection values) + { + return Join(separator, values.AsEnumerable()); + } + /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { diff --git a/tests/ZString.Tests/JoinTest.cs b/tests/ZString.Tests/JoinTest.cs index 790831e6..7a20ccef 100644 --- a/tests/ZString.Tests/JoinTest.cs +++ b/tests/ZString.Tests/JoinTest.cs @@ -63,6 +63,35 @@ public void JoinOverloads2() ZString.Join("_,_", (IReadOnlyCollection)new[] { 1, 2, 3 }).Should().Be(string.Join("_,_", new[] { 1, 2, 3 })); } + [Fact] + public void JoinOverloads3() + { + ZString.Join(',', new string[] { }.ToList()).Should().Be(string.Join(',', new string[0])); + ZString.Join(',', new[] { 1 }.ToList()).Should().Be(string.Join(',', new[] { 1 })); + ZString.Join(',', new[] { 1, 2 }.ToList()).Should().Be(string.Join(',', new[] { 1, 2 })); + ZString.Join(',', new[] { 1, 2, 3 }.ToList()).Should().Be(string.Join(',', new[] { 1, 2, 3 })); + + ZString.Join(',', (IList)new int[] { }).Should().Be(string.Join(',', new string[0])); + ZString.Join(',', (IList)new[] { 1 }).Should().Be(string.Join(',', new[] { 1 })); + ZString.Join(',', (IList)new[] { 1, 2 }).Should().Be(string.Join(',', new[] { 1, 2 })); + ZString.Join(',', (IList)new[] { 1, 2, 3 }).Should().Be(string.Join(',', new[] { 1, 2, 3 })); + + ZString.Join(',', (IReadOnlyList)new int[] { }).Should().Be(string.Join(',', new string[0])); + ZString.Join(',', (IReadOnlyList)new[] { 1 }).Should().Be(string.Join(',', new[] { 1 })); + ZString.Join(',', (IReadOnlyList)new[] { 1, 2 }).Should().Be(string.Join(',', new[] { 1, 2 })); + ZString.Join(',', (IReadOnlyList)new[] { 1, 2, 3 }).Should().Be(string.Join(',', new[] { 1, 2, 3 })); + + ZString.Join(',', (ICollection)new int[] { }).Should().Be(string.Join(',', new string[0])); + ZString.Join(',', (ICollection)new[] { 1 }).Should().Be(string.Join(',', new[] { 1 })); + ZString.Join(',', (ICollection)new[] { 1, 2 }).Should().Be(string.Join(',', new[] { 1, 2 })); + ZString.Join(',', (ICollection)new[] { 1, 2, 3 }).Should().Be(string.Join(',', new[] { 1, 2, 3 })); + + ZString.Join(',', (IReadOnlyCollection)new int[] { }).Should().Be(string.Join(',', new string[0])); + ZString.Join(',', (IReadOnlyCollection)new[] { 1 }).Should().Be(string.Join(',', new[] { 1 })); + ZString.Join(',', (IReadOnlyCollection)new[] { 1, 2 }).Should().Be(string.Join(',', new[] { 1, 2 })); + ZString.Join(',', (IReadOnlyCollection)new[] { 1, 2, 3 }).Should().Be(string.Join(',', new[] { 1, 2, 3 })); + } + [Fact] public void CooncatNullTest() { From 24978c3a852de60c93c5a06e1640e89c17eac024 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Fri, 8 May 2020 23:23:23 +0900 Subject: [PATCH 043/139] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 13e84964..d8708668 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,12 @@ void BuildMessage(ref Utf16ValueStringBuilder builder) } ``` +--- + + Utf8Format, Utf8StringBuilder uses [Utf8Formatter.TryFormat](https://docs.microsoft.com/en-us/dotnet/api/system.buffers.text.utf8formatter.tryformat) and there format string is not same as standard format. It uses [StandardFormat](https://docs.microsoft.com/en-us/dotnet/api/system.buffers.standardformat), combinate of symbol char and precision. Supported format string symbol can find in Utf8Formatter.TryFormat document(For example Int32 supports `G`, `D`, `N`, `X` and Boolean supports `G`, `I`). Precision(zero padding) can pass after symbol like `D2`. For example `sb.AppendFormat("{0:D2}:{1:D2}:{2:D2}", hour, minute, second)`. + +[TryFormat(DateTime)](https://docs.microsoft.com/en-us/dotnet/api/system.buffers.text.utf8formatter.tryformat?view=netcore-3.1#System_Buffers_Text_Utf8Formatter_TryFormat_System_DateTime_System_Span_System_Byte__System_Int32__System_Buffers_StandardFormat_) and [TryFormat(TimeSpan)](https://docs.microsoft.com/en-us/dotnet/api/system.buffers.text.utf8formatter.tryformat?view=netcore-3.1#System_Buffers_Text_Utf8Formatter_TryFormat_System_TimeSpan_System_Span_System_Byte__System_Int32__System_Buffers_StandardFormat_) symbol is too restricted than standard string format. If you want to use custom format, deconstruct there `Day`, `Hour`, etc. + --- `Utf8ValueStringBuilder` and `Utf16ValueStringBuilder` implements `IBufferWriter` so you can pass serializer(such as `JsonSerializer` of `System.Text.Json`). But be careful to boxing copy, `ValueStringBuilder` is mutable struct. For example, From 06e03c3ce5c2cbac4306487b87eb50ba767c0e2d Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 11 May 2020 11:15:18 +0900 Subject: [PATCH 044/139] format parser does not handle escape character #16 --- sandbox/ConsoleApp/Program.cs | 9 +++++---- .../Assets/Scripts/ZString/FormatParser.cs | 2 +- src/ZString/FormatParser.cs | 2 +- tests/ZString.Tests/FormatTest.cs | 10 ++++++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index e7634073..b1b0290d 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -25,12 +25,13 @@ static void Main(string[] args) static void Run() { -var a = new string('a', 10000); -var b = new string('b', 1000000); + TimeSpan span = new TimeSpan(12, 34, 56); + Console.WriteLine($"string.Format: {string.Format(@"{0:h\,h\:mm\:ss}", span)}"); + + + Console.WriteLine($"ZString.Format: {ZString.Format(@"{0:h\,h\:mm\:ss}", span)}"); -ZString.Join(',', new string[] { a, b }); - } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs b/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs index 9808ef47..eed62867 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs @@ -42,7 +42,7 @@ public static ParseResult Parse(ReadOnlySpan format) } } - if (index == -1 && format[i] == ',' || format[i] == ':') + if (index == -1 && (format[i] == ',' && format[i - 1] != '\\') || (format[i] == ':' && format[i - 1] != '\\')) { index = Int32.Parse(format.Slice(1, i - 1)); formatStart = i + 1; diff --git a/src/ZString/FormatParser.cs b/src/ZString/FormatParser.cs index 9808ef47..eed62867 100644 --- a/src/ZString/FormatParser.cs +++ b/src/ZString/FormatParser.cs @@ -42,7 +42,7 @@ public static ParseResult Parse(ReadOnlySpan format) } } - if (index == -1 && format[i] == ',' || format[i] == ':') + if (index == -1 && (format[i] == ',' && format[i - 1] != '\\') || (format[i] == ':' && format[i - 1] != '\\')) { index = Int32.Parse(format.Slice(1, i - 1)); formatStart = i + 1; diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index 67a5da15..ae32d52c 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -96,5 +96,15 @@ public void FormatArgs() { ZString.Format("{0:00000000}-{1:00000000}", 100, 200).Should().Be("00000100-00000200"); } + + [Fact] + public void Escape() + { + TimeSpan span = new TimeSpan(12, 34, 56); + var reference = string.Format(@"{0:h\,h\:mm\:ss}", span); + + var actual = ZString.Format(@"{0:h\,h\:mm\:ss}", span); + actual.Should().Be(reference); + } } } \ No newline at end of file From 1da66d1e2d51f424d7f7a69825a5c34a0fec8a04 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Thu, 14 May 2020 08:51:43 +0900 Subject: [PATCH 045/139] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d8708668..1c147ae2 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ All `ZString` methods only allocate final string. Also, `ZString` has enabled to The blog post of detailed explanation by author: [medium@neuecc/ZString](https://medium.com/@neuecc/zstring-zero-allocation-stringbuilder-for-net-core-and-unity-f3163c88c887) +Related project for loggin using with ZString, [Cysharp/ZLogger](https://github.com/Cysharp/ZLogger) - Zero Allocation Text/Strcutured Logger. + Getting Started --- For .NET Core, use NuGet. From 49a9e3725ba05ed492c6043326d51a7c20bc179c Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 20 Jun 2020 10:09:53 +0900 Subject: [PATCH 046/139] Improved the performance of ZString.Join when the type parameter is of type String. --- .../Benchmarks/StringListJoinBenchmark.cs | 100 +++++++++++++++++ .../Assets/Scripts/ZString/ZString.cs | 103 ++++++++++++++++-- src/ZString/ZString.cs | 103 ++++++++++++++++-- tests/ZString.Tests/JoinTest.cs | 23 ++++ 4 files changed, 313 insertions(+), 16 deletions(-) create mode 100644 sandbox/PerfBenchmark/Benchmarks/StringListJoinBenchmark.cs diff --git a/sandbox/PerfBenchmark/Benchmarks/StringListJoinBenchmark.cs b/sandbox/PerfBenchmark/Benchmarks/StringListJoinBenchmark.cs new file mode 100644 index 00000000..2c16a0ae --- /dev/null +++ b/sandbox/PerfBenchmark/Benchmarks/StringListJoinBenchmark.cs @@ -0,0 +1,100 @@ +using BenchmarkDotNet.Attributes; +using Cysharp.Text; +using System; +using System.Collections.Generic; +using System.Linq; +namespace PerfBenchmark.Benchmarks +{ + [Config(typeof(BenchmarkConfig))] + public class StringListJoinBenchmark + { + //private const char Separator = ','; + private const string Separator = ","; + + List _emptyList; + IEnumerable _enum1; + string[] _array1; + List _list1; + IEnumerable _enum2; + string[] _array2; + List _list2; + IEnumerable _enum10; + List _list10; + string[] _array10; + + public StringListJoinBenchmark() + { + _emptyList = new List(); + _enum1 = Enumerable.Repeat(Guid.NewGuid().ToString(), 1); + _list1 = _enum1.ToList(); + _array1 = _enum1.ToArray(); + _enum2 = Enumerable.Repeat(Guid.NewGuid().ToString(), 2); + _list2 = _enum2.ToList(); + _array2 = _enum2.ToArray(); + _enum10 = Enumerable.Repeat(Guid.NewGuid().ToString(), 10); + _list10 = _enum10.ToList(); + _array10 = _enum10.ToArray(); + } + + [Benchmark] + public string JoinEmptyList() => String.Join(Separator, _emptyList); + + [Benchmark] + public string ZJoinEmptyList() => ZString.Join(Separator, _emptyList); + + [Benchmark] + public string JoinList1() => String.Join(Separator, _list1); + + [Benchmark] + public string ZJoinList1() => ZString.Join(Separator, _list1); + + [Benchmark] + public string JoinArray1() => String.Join(Separator, _array1); + + [Benchmark] + public string ZJoinArray1() => ZString.Join(Separator, _array1); + + [Benchmark] + public string JoinEnumerable1() => String.Join(Separator, _enum1); + + [Benchmark] + public string ZJoinEnumerable1() => ZString.Join(Separator, _enum1); + + [Benchmark] + public string JoinList2() => String.Join(Separator, _list2); + + [Benchmark] + public string ZJoinList2() => ZString.Join(Separator, _list2); + + [Benchmark] + public string JoinArray2() => String.Join(Separator, _array2); + + [Benchmark] + public string ZJoinArray2() => ZString.Join(Separator, _array2); + + [Benchmark] + public string JoinEnumerable2() => String.Join(Separator, _enum2); + + [Benchmark] + public string ZJoinEnumerable2() => ZString.Join(Separator, _enum2); + + [Benchmark] + public string JoinList10() => String.Join(Separator, _list10); + + [Benchmark] + public string ZJoinList10() => ZString.Join(Separator, _list10); + + [Benchmark] + public string JoinArray10() => String.Join(Separator, _array10); + + [Benchmark] + public string ZJoinArray10() => ZString.Join(Separator, _array10); + + [Benchmark] + public string JoinEnumerable10() => String.Join(Separator, _enum10); + + [Benchmark] + public string ZJoinEnumerable10() => ZString.Join(Separator, _enum10); + + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 8c02e802..9e8b384c 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; namespace Cysharp.Text @@ -45,7 +46,18 @@ public static string Join(char separator, params T[] values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -68,7 +80,18 @@ public static string Join(char separator, List values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -90,7 +113,18 @@ public static string Join(char separator, ReadOnlySpan values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -117,7 +151,17 @@ public static string Join(char separator, IEnumerable values) { isFirst = false; } - sb.Append(item); + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); @@ -160,7 +204,18 @@ public static string Join(string separator, params T[] values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -183,7 +238,18 @@ public static string Join(string separator, List values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -205,7 +271,18 @@ public static string Join(string separator, ReadOnlySpan values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -252,7 +329,17 @@ public static string Join(string separator, IEnumerable values) { isFirst = false; } - sb.Append(item); + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 8c02e802..9e8b384c 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; namespace Cysharp.Text @@ -45,7 +46,18 @@ public static string Join(char separator, params T[] values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -68,7 +80,18 @@ public static string Join(char separator, List values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -90,7 +113,18 @@ public static string Join(char separator, ReadOnlySpan values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -117,7 +151,17 @@ public static string Join(char separator, IEnumerable values) { isFirst = false; } - sb.Append(item); + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); @@ -160,7 +204,18 @@ public static string Join(string separator, params T[] values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -183,7 +238,18 @@ public static string Join(string separator, List values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -205,7 +271,18 @@ public static string Join(string separator, ReadOnlySpan values) { sb.Append(separator); } - sb.Append(values[i]); + var item = values[i]; + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); } @@ -252,7 +329,17 @@ public static string Join(string separator, IEnumerable values) { isFirst = false; } - sb.Append(item); + if (typeof(T) == typeof(string)) + { + if (item != null) + { + sb.Append(Unsafe.As(item)); + } + } + else + { + sb.Append(item); + } } return sb.ToString(); diff --git a/tests/ZString.Tests/JoinTest.cs b/tests/ZString.Tests/JoinTest.cs index 7a20ccef..ed4ddd6b 100644 --- a/tests/ZString.Tests/JoinTest.cs +++ b/tests/ZString.Tests/JoinTest.cs @@ -109,5 +109,28 @@ public void ConcatHugeString() var expected = string.Join(',', new string[] { a, b }); actrual.Should().Be(expected); } + + [Fact] + public void JoinStrings() + { + var values = new[] { "abc", null, "def" }; + { + const char sep = ','; + var expected = string.Join(sep, values); + ZString.Join(sep, new ReadOnlySpan(values)).Should().Be(expected); + ZString.Join(sep, values).Should().Be(expected); + ZString.Join(sep, values.ToList()).Should().Be(expected); + ZString.Join(sep, values.AsEnumerable()).Should().Be(expected); + } + + { + const string sep = "_,_"; + var expected = string.Join(sep, values); + ZString.Join(sep, new ReadOnlySpan(values)).Should().Be(expected); + ZString.Join(sep, values).Should().Be(expected); + ZString.Join(sep, values.ToList()).Should().Be(expected); + ZString.Join(sep, values.AsEnumerable()).Should().Be(expected); + } + } } } From b31b7eee34d9954700bf7c4268faa6796f120cf5 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 20 Jun 2020 16:00:58 +0900 Subject: [PATCH 047/139] Add Utf16ValueStringBuilder.Append(ReadOnlySpan value) --- .../Assets/Scripts/ZString/Utf16ValueStringBuilder.cs | 9 ++++++++- src/ZString/Utf16ValueStringBuilder.cs | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 76809a18..b589b3d4 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -157,13 +157,20 @@ public void AppendLine(char value) /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) + { + Append(value.AsSpan()); + } + + /// Appends a contiguous region of arbitrary memory to this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(ReadOnlySpan value) { if (buffer.Length - index < value.Length) { Grow(value.Length); } - value.CopyTo(0, buffer, index, value.Length); + value.CopyTo(buffer.AsSpan(index)); index += value.Length; } diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 76809a18..b589b3d4 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -157,13 +157,20 @@ public void AppendLine(char value) /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) + { + Append(value.AsSpan()); + } + + /// Appends a contiguous region of arbitrary memory to this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(ReadOnlySpan value) { if (buffer.Length - index < value.Length) { Grow(value.Length); } - value.CopyTo(0, buffer, index, value.Length); + value.CopyTo(buffer.AsSpan(index)); index += value.Length; } From 6b927164329990bfb39927bc72832e351587fe08 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 20 Jun 2020 16:43:18 +0900 Subject: [PATCH 048/139] Cleaned up ZString.Join --- .../Assets/Scripts/ZString/ZString.cs | 222 ++++-------------- src/ZString/ZString.cs | 222 ++++-------------- 2 files changed, 102 insertions(+), 342 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 9e8b384c..cbb6b24b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -37,139 +37,27 @@ public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, params T[] values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - var item = values[i]; - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + return Join(separator, (IList)values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, List values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - var count = values.Count; - for (int i = 0; i < count; i++) - { - if (i != 0) - { - sb.Append(separator); - } - var item = values[i]; - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + return Join(separator, (IList)values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - var item = values[i]; - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + Span s = stackalloc char[1] { separator }; + return JoinInternal(s, values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, IEnumerable values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - var isFirst = true; - foreach (var item in values) - { - if (!isFirst) - { - sb.Append(separator); - } - else - { - isFirst = false; - } - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + Span s = stackalloc char[1] { separator }; + return JoinInternal(s, values); } public static string Join(char separator, ICollection values) @@ -179,7 +67,8 @@ public static string Join(char separator, ICollection values) public static string Join(char separator, IList values) { - return Join(separator, values.AsEnumerable()); + Span s = stackalloc char[1] { separator }; + return JoinInternal(s, values); } public static string Join(char separator, IReadOnlyList values) @@ -195,38 +84,48 @@ public static string Join(char separator, IReadOnlyCollection values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - var item = values[i]; - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + return JoinInternal(separator.AsSpan(), values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, List values) + { + return JoinInternal(separator.AsSpan(), values); + } + + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(string separator, ReadOnlySpan values) + { + return JoinInternal(separator.AsSpan(), values); + } + + public static string Join(string separator, ICollection values) + { + return JoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public static string Join(string separator, IList values) + { + return JoinInternal(separator.AsSpan(), values); + } + + public static string Join(string separator, IReadOnlyList values) + { + return JoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public static string Join(string separator, IReadOnlyCollection values) + { + return JoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(string separator, IEnumerable values) + { + return JoinInternal(separator.AsSpan(), values); + } + + static string JoinInternal(ReadOnlySpan separator, IList values) { var sb = new Utf16ValueStringBuilder(true); try @@ -238,6 +137,7 @@ public static string Join(string separator, List values) { sb.Append(separator); } + var item = values[i]; if (typeof(T) == typeof(string)) { @@ -259,8 +159,7 @@ public static string Join(string separator, List values) } } - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(string separator, ReadOnlySpan values) + static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) { var sb = new Utf16ValueStringBuilder(true); try @@ -271,6 +170,7 @@ public static string Join(string separator, ReadOnlySpan values) { sb.Append(separator); } + var item = values[i]; if (typeof(T) == typeof(string)) { @@ -292,28 +192,7 @@ public static string Join(string separator, ReadOnlySpan values) } } - public static string Join(string separator, ICollection values) - { - return Join(separator, values.AsEnumerable()); - } - - public static string Join(string separator, IList values) - { - return Join(separator, values.AsEnumerable()); - } - - public static string Join(string separator, IReadOnlyList values) - { - return Join(separator, values.AsEnumerable()); - } - - public static string Join(string separator, IReadOnlyCollection values) - { - return Join(separator, values.AsEnumerable()); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(string separator, IEnumerable values) + static string JoinInternal(ReadOnlySpan separator, IEnumerable values) { var sb = new Utf16ValueStringBuilder(true); try @@ -329,6 +208,7 @@ public static string Join(string separator, IEnumerable values) { isFirst = false; } + if (typeof(T) == typeof(string)) { if (item != null) diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 9e8b384c..cbb6b24b 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -37,139 +37,27 @@ public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, params T[] values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - var item = values[i]; - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + return Join(separator, (IList)values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, List values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - var count = values.Count; - for (int i = 0; i < count; i++) - { - if (i != 0) - { - sb.Append(separator); - } - var item = values[i]; - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + return Join(separator, (IList)values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - var item = values[i]; - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + Span s = stackalloc char[1] { separator }; + return JoinInternal(s, values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, IEnumerable values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - var isFirst = true; - foreach (var item in values) - { - if (!isFirst) - { - sb.Append(separator); - } - else - { - isFirst = false; - } - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + Span s = stackalloc char[1] { separator }; + return JoinInternal(s, values); } public static string Join(char separator, ICollection values) @@ -179,7 +67,8 @@ public static string Join(char separator, ICollection values) public static string Join(char separator, IList values) { - return Join(separator, values.AsEnumerable()); + Span s = stackalloc char[1] { separator }; + return JoinInternal(s, values); } public static string Join(char separator, IReadOnlyList values) @@ -195,38 +84,48 @@ public static string Join(char separator, IReadOnlyCollection values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - var item = values[i]; - if (typeof(T) == typeof(string)) - { - if (item != null) - { - sb.Append(Unsafe.As(item)); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } + return JoinInternal(separator.AsSpan(), values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, List values) + { + return JoinInternal(separator.AsSpan(), values); + } + + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(string separator, ReadOnlySpan values) + { + return JoinInternal(separator.AsSpan(), values); + } + + public static string Join(string separator, ICollection values) + { + return JoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public static string Join(string separator, IList values) + { + return JoinInternal(separator.AsSpan(), values); + } + + public static string Join(string separator, IReadOnlyList values) + { + return JoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public static string Join(string separator, IReadOnlyCollection values) + { + return JoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + /// Concatenates the elements of an array, using the specified seperator between each element. + public static string Join(string separator, IEnumerable values) + { + return JoinInternal(separator.AsSpan(), values); + } + + static string JoinInternal(ReadOnlySpan separator, IList values) { var sb = new Utf16ValueStringBuilder(true); try @@ -238,6 +137,7 @@ public static string Join(string separator, List values) { sb.Append(separator); } + var item = values[i]; if (typeof(T) == typeof(string)) { @@ -259,8 +159,7 @@ public static string Join(string separator, List values) } } - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(string separator, ReadOnlySpan values) + static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) { var sb = new Utf16ValueStringBuilder(true); try @@ -271,6 +170,7 @@ public static string Join(string separator, ReadOnlySpan values) { sb.Append(separator); } + var item = values[i]; if (typeof(T) == typeof(string)) { @@ -292,28 +192,7 @@ public static string Join(string separator, ReadOnlySpan values) } } - public static string Join(string separator, ICollection values) - { - return Join(separator, values.AsEnumerable()); - } - - public static string Join(string separator, IList values) - { - return Join(separator, values.AsEnumerable()); - } - - public static string Join(string separator, IReadOnlyList values) - { - return Join(separator, values.AsEnumerable()); - } - - public static string Join(string separator, IReadOnlyCollection values) - { - return Join(separator, values.AsEnumerable()); - } - - /// Concatenates the elements of an array, using the specified seperator between each element. - public static string Join(string separator, IEnumerable values) + static string JoinInternal(ReadOnlySpan separator, IEnumerable values) { var sb = new Utf16ValueStringBuilder(true); try @@ -329,6 +208,7 @@ public static string Join(string separator, IEnumerable values) { isFirst = false; } + if (typeof(T) == typeof(string)) { if (item != null) From 6b94c72461b7672ae621ffc0dd1c8c5224894a45 Mon Sep 17 00:00:00 2001 From: udaken Date: Sun, 21 Jun 2020 15:26:48 +0900 Subject: [PATCH 049/139] Optimized for small list. --- .../Assets/Scripts/ZString/ZString.cs | 48 ++++++++++++++----- src/ZString/ZString.cs | 48 ++++++++++++++----- 2 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index cbb6b24b..5f18008a 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -37,7 +37,8 @@ public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, params T[] values) { - return Join(separator, (IList)values); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, values.AsSpan()); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -49,14 +50,14 @@ public static string Join(char separator, List values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { - Span s = stackalloc char[1] { separator }; + ReadOnlySpan s = stackalloc char[1] { separator }; return JoinInternal(s, values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, IEnumerable values) { - Span s = stackalloc char[1] { separator }; + ReadOnlySpan s = stackalloc char[1] { separator }; return JoinInternal(s, values); } @@ -67,7 +68,7 @@ public static string Join(char separator, ICollection values) public static string Join(char separator, IList values) { - Span s = stackalloc char[1] { separator }; + ReadOnlySpan s = stackalloc char[1] { separator }; return JoinInternal(s, values); } @@ -84,7 +85,7 @@ public static string Join(char separator, IReadOnlyCollection values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { - return JoinInternal(separator.AsSpan(), values); + return JoinInternal(separator.AsSpan(), values.AsSpan()); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -95,7 +96,7 @@ public static string Join(string separator, List values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, ReadOnlySpan values) - { + { return JoinInternal(separator.AsSpan(), values); } @@ -127,10 +128,19 @@ public static string Join(string separator, IEnumerable values) static string JoinInternal(ReadOnlySpan separator, IList values) { + var count = values.Count; + if (count == 0) + { + return string.Empty; + } + else if (typeof(T) == typeof(string) && count == 1) + { + return Unsafe.As(values[0]); + } + var sb = new Utf16ValueStringBuilder(true); try { - var count = values.Count; for (int i = 0; i < count; i++) { if (i != 0) @@ -141,9 +151,10 @@ static string JoinInternal(ReadOnlySpan separator, IList values) var item = values[i]; if (typeof(T) == typeof(string)) { - if (item != null) + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) { - sb.Append(Unsafe.As(item)); + sb.Append(s); } } else @@ -161,6 +172,15 @@ static string JoinInternal(ReadOnlySpan separator, IList values) static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) { + if (values.Length == 0) + { + return string.Empty; + } + else if (typeof(T) == typeof(string) && values.Length == 1) + { + return Unsafe.As(values[0]); + } + var sb = new Utf16ValueStringBuilder(true); try { @@ -174,9 +194,10 @@ static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan valu var item = values[i]; if (typeof(T) == typeof(string)) { - if (item != null) + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) { - sb.Append(Unsafe.As(item)); + sb.Append(s); } } else @@ -211,9 +232,10 @@ static string JoinInternal(ReadOnlySpan separator, IEnumerable value if (typeof(T) == typeof(string)) { - if (item != null) + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) { - sb.Append(Unsafe.As(item)); + sb.Append(s); } } else diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index cbb6b24b..5f18008a 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -37,7 +37,8 @@ public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, params T[] values) { - return Join(separator, (IList)values); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, values.AsSpan()); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -49,14 +50,14 @@ public static string Join(char separator, List values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, ReadOnlySpan values) { - Span s = stackalloc char[1] { separator }; + ReadOnlySpan s = stackalloc char[1] { separator }; return JoinInternal(s, values); } /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, IEnumerable values) { - Span s = stackalloc char[1] { separator }; + ReadOnlySpan s = stackalloc char[1] { separator }; return JoinInternal(s, values); } @@ -67,7 +68,7 @@ public static string Join(char separator, ICollection values) public static string Join(char separator, IList values) { - Span s = stackalloc char[1] { separator }; + ReadOnlySpan s = stackalloc char[1] { separator }; return JoinInternal(s, values); } @@ -84,7 +85,7 @@ public static string Join(char separator, IReadOnlyCollection values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, params T[] values) { - return JoinInternal(separator.AsSpan(), values); + return JoinInternal(separator.AsSpan(), values.AsSpan()); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -95,7 +96,7 @@ public static string Join(string separator, List values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, ReadOnlySpan values) - { + { return JoinInternal(separator.AsSpan(), values); } @@ -127,10 +128,19 @@ public static string Join(string separator, IEnumerable values) static string JoinInternal(ReadOnlySpan separator, IList values) { + var count = values.Count; + if (count == 0) + { + return string.Empty; + } + else if (typeof(T) == typeof(string) && count == 1) + { + return Unsafe.As(values[0]); + } + var sb = new Utf16ValueStringBuilder(true); try { - var count = values.Count; for (int i = 0; i < count; i++) { if (i != 0) @@ -141,9 +151,10 @@ static string JoinInternal(ReadOnlySpan separator, IList values) var item = values[i]; if (typeof(T) == typeof(string)) { - if (item != null) + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) { - sb.Append(Unsafe.As(item)); + sb.Append(s); } } else @@ -161,6 +172,15 @@ static string JoinInternal(ReadOnlySpan separator, IList values) static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) { + if (values.Length == 0) + { + return string.Empty; + } + else if (typeof(T) == typeof(string) && values.Length == 1) + { + return Unsafe.As(values[0]); + } + var sb = new Utf16ValueStringBuilder(true); try { @@ -174,9 +194,10 @@ static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan valu var item = values[i]; if (typeof(T) == typeof(string)) { - if (item != null) + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) { - sb.Append(Unsafe.As(item)); + sb.Append(s); } } else @@ -211,9 +232,10 @@ static string JoinInternal(ReadOnlySpan separator, IEnumerable value if (typeof(T) == typeof(string)) { - if (item != null) + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) { - sb.Append(Unsafe.As(item)); + sb.Append(s); } } else From 99ba1172bcc2d74b14ef5ebeb3ae3e651c5a7a29 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 29 Jun 2020 17:10:36 +0900 Subject: [PATCH 050/139] unity --- .gitignore | 2 + .../Assets/Scripts/Editor/PackageExporter.cs | 42 ++++++++++++++++-- .../ZString/IResettableBufferWriter.cs.meta | 11 +++++ src/ZString.Unity/ZString.Unity.unitypackage | Bin 183356 -> 0 bytes 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/IResettableBufferWriter.cs.meta delete mode 100644 src/ZString.Unity/ZString.Unity.unitypackage diff --git a/.gitignore b/.gitignore index 67a15a7f..abc89380 100644 --- a/.gitignore +++ b/.gitignore @@ -121,3 +121,5 @@ src/ZString.Unity/Assembly-CSharp.csproj src/ZString.Unity/Assembly-CSharp-Editor.csproj src/ZString.Unity/ZString.csproj src/ZString.Unity/ZString.Unity.sln + +src/ZString.Unity/ZString.Unity.unitypackage diff --git a/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs b/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs index b162f23d..9b8e80c8 100644 --- a/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs +++ b/src/ZString.Unity/Assets/Scripts/Editor/PackageExporter.cs @@ -9,10 +9,9 @@ public static class PackageExporter [MenuItem("Tools/Export Unitypackage")] public static void Export() { - var version = Environment.GetEnvironmentVariable("UNITY_PACKAGE_VERSION"); - - // configure var root = "Scripts/ZString"; + var version = GetVersion(root); + var fileName = string.IsNullOrEmpty(version) ? "ZString.Unity.unitypackage" : $"ZString.Unity.{version}.unitypackage"; var exportPath = "./" + fileName; @@ -40,4 +39,41 @@ public static void Export() UnityEngine.Debug.Log("Export complete: " + Path.GetFullPath(exportPath)); } + + static string GetVersion(string root) + { + var version = Environment.GetEnvironmentVariable("UNITY_PACKAGE_VERSION"); + var versionJson = Path.Combine(Application.dataPath, root, "package.json"); + + if (File.Exists(versionJson)) + { + var v = JsonUtility.FromJson(File.ReadAllText(versionJson)); + + if (!string.IsNullOrEmpty(version)) + { + if (v.version != version) + { + var msg = $"package.json and env version are mismatched. UNITY_PACKAGE_VERSION:{version}, package.json:{v.version}"; + + if (Application.isBatchMode) + { + Console.WriteLine(msg); + Application.Quit(1); + } + + throw new Exception("package.json and env version are mismatched."); + } + } + + version = v.version; + } + + return version; + } + + public class Version + { + public string version; + } + } \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/IResettableBufferWriter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/IResettableBufferWriter.cs.meta new file mode 100644 index 00000000..22b2e64b --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/IResettableBufferWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c853a6364ab3cd3489eaaab75fbb2f5b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/ZString.Unity.unitypackage b/src/ZString.Unity/ZString.Unity.unitypackage deleted file mode 100644 index d6fd0d4e823d44567e06e52d773e667039fc38c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183356 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%0AT0a%?Iz+p#d!clt!4Q_yak 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 Date: Tue, 30 Jun 2020 00:51:41 +0900 Subject: [PATCH 051/139] Implement Concat methods from collections --- .../Assets/Scripts/ZString/ZString.cs | 154 ++++++++++++++++++ src/ZString/ZString.cs | 154 ++++++++++++++++++ 2 files changed, 308 insertions(+) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 5f18008a..ba66398e 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -251,5 +251,159 @@ static string JoinInternal(ReadOnlySpan separator, IEnumerable value sb.Dispose(); } } + + /// Concatenates the string representation of some specified objects. + public static string Concat(params T[] values) + { + return ConcatInternal(values.AsSpan()); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(List values) + { + return ConcatInternal(values); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(ReadOnlySpan values) + { + return ConcatInternal(values); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(ICollection values) + { + return ConcatInternal(values.AsEnumerable()); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(IList values) + { + return ConcatInternal(values); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(IReadOnlyList values) + { + return ConcatInternal(values.AsEnumerable()); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(IReadOnlyCollection values) + { + return ConcatInternal(values.AsEnumerable()); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(IEnumerable values) + { + return ConcatInternal(values); + } + + static string ConcatInternal(IList values) + { + var count = values.Count; + if (count == 0) + { + return string.Empty; + } + else if (typeof(T) == typeof(string) && count == 1) + { + return Unsafe.As(values[0]); + } + + var sb = new Utf16ValueStringBuilder(true); + try + { + for (int i = 0; i < count; i++) + { + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + sb.Append(s); + } + } + else + { + sb.Append(item); + } + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + static string ConcatInternal(ReadOnlySpan values) + { + if (values.Length == 0) + { + return string.Empty; + } + else if (typeof(T) == typeof(string) && values.Length == 1) + { + return Unsafe.As(values[0]); + } + + var sb = new Utf16ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + sb.Append(s); + } + } + else + { + sb.Append(item); + } + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + static string ConcatInternal(IEnumerable values) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + foreach (var item in values) + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + sb.Append(s); + } + } + else + { + sb.Append(item); + } + } + + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } } } diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 5f18008a..ba66398e 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -251,5 +251,159 @@ static string JoinInternal(ReadOnlySpan separator, IEnumerable value sb.Dispose(); } } + + /// Concatenates the string representation of some specified objects. + public static string Concat(params T[] values) + { + return ConcatInternal(values.AsSpan()); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(List values) + { + return ConcatInternal(values); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(ReadOnlySpan values) + { + return ConcatInternal(values); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(ICollection values) + { + return ConcatInternal(values.AsEnumerable()); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(IList values) + { + return ConcatInternal(values); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(IReadOnlyList values) + { + return ConcatInternal(values.AsEnumerable()); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(IReadOnlyCollection values) + { + return ConcatInternal(values.AsEnumerable()); + } + + /// Concatenates the string representation of some specified objects. + public static string Concat(IEnumerable values) + { + return ConcatInternal(values); + } + + static string ConcatInternal(IList values) + { + var count = values.Count; + if (count == 0) + { + return string.Empty; + } + else if (typeof(T) == typeof(string) && count == 1) + { + return Unsafe.As(values[0]); + } + + var sb = new Utf16ValueStringBuilder(true); + try + { + for (int i = 0; i < count; i++) + { + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + sb.Append(s); + } + } + else + { + sb.Append(item); + } + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + static string ConcatInternal(ReadOnlySpan values) + { + if (values.Length == 0) + { + return string.Empty; + } + else if (typeof(T) == typeof(string) && values.Length == 1) + { + return Unsafe.As(values[0]); + } + + var sb = new Utf16ValueStringBuilder(true); + try + { + for (int i = 0; i < values.Length; i++) + { + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + sb.Append(s); + } + } + else + { + sb.Append(item); + } + } + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } + + static string ConcatInternal(IEnumerable values) + { + var sb = new Utf16ValueStringBuilder(true); + try + { + foreach (var item in values) + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + sb.Append(s); + } + } + else + { + sb.Append(item); + } + } + + return sb.ToString(); + } + finally + { + sb.Dispose(); + } + } } } From 1fd77f2b5d02c9144134f9bf827545f5f83b5682 Mon Sep 17 00:00:00 2001 From: piti6 Date: Tue, 30 Jun 2020 00:51:50 +0900 Subject: [PATCH 052/139] Implement Test --- tests/ZString.Tests/JoinTest.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/ZString.Tests/JoinTest.cs b/tests/ZString.Tests/JoinTest.cs index ed4ddd6b..d832e122 100644 --- a/tests/ZString.Tests/JoinTest.cs +++ b/tests/ZString.Tests/JoinTest.cs @@ -132,5 +132,17 @@ public void JoinStrings() ZString.Join(sep, values.AsEnumerable()).Should().Be(expected); } } + + [Fact] + public void ConcatStrings() + { + var values = new[] { "abc", null, "def" }; + + var expected = string.Concat(values); + ZString.Concat(new ReadOnlySpan(values)).Should().Be(expected); + ZString.Concat(values).Should().Be(expected); + ZString.Concat(values.ToList()).Should().Be(expected); + ZString.Concat(values.AsEnumerable()).Should().Be(expected); + } } } From e2c431f90cc872289d07b174231083474888dc2e Mon Sep 17 00:00:00 2001 From: piti6 Date: Thu, 2 Jul 2020 20:03:49 +0900 Subject: [PATCH 053/139] Remove duplicated codes --- .../Assets/Scripts/ZString/ZString.cs | 168 ++++-------------- src/ZString/ZString.cs | 168 ++++-------------- 2 files changed, 62 insertions(+), 274 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index ba66398e..560c92e5 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -126,181 +126,55 @@ public static string Join(string separator, IEnumerable values) return JoinInternal(separator.AsSpan(), values); } - static string JoinInternal(ReadOnlySpan separator, IList values) - { - var count = values.Count; - if (count == 0) - { - return string.Empty; - } - else if (typeof(T) == typeof(string) && count == 1) - { - return Unsafe.As(values[0]); - } - - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < count; i++) - { - if (i != 0) - { - sb.Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) - { - if (values.Length == 0) - { - return string.Empty; - } - else if (typeof(T) == typeof(string) && values.Length == 1) - { - return Unsafe.As(values[0]); - } - - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - static string JoinInternal(ReadOnlySpan separator, IEnumerable values) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - var isFirst = true; - foreach (var item in values) - { - if (!isFirst) - { - sb.Append(separator); - } - else - { - isFirst = false; - } - - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - /// Concatenates the string representation of some specified objects. public static string Concat(params T[] values) { - return ConcatInternal(values.AsSpan()); + return JoinInternal(default, values.AsSpan()); } /// Concatenates the string representation of some specified objects. public static string Concat(List values) { - return ConcatInternal(values); + return JoinInternal(default, values); } /// Concatenates the string representation of some specified objects. public static string Concat(ReadOnlySpan values) { - return ConcatInternal(values); + return JoinInternal(default, values); } /// Concatenates the string representation of some specified objects. public static string Concat(ICollection values) { - return ConcatInternal(values.AsEnumerable()); + return JoinInternal(default, values.AsEnumerable()); } /// Concatenates the string representation of some specified objects. public static string Concat(IList values) { - return ConcatInternal(values); + return JoinInternal(default, values); } /// Concatenates the string representation of some specified objects. public static string Concat(IReadOnlyList values) { - return ConcatInternal(values.AsEnumerable()); + return JoinInternal(default, values.AsEnumerable()); } /// Concatenates the string representation of some specified objects. public static string Concat(IReadOnlyCollection values) { - return ConcatInternal(values.AsEnumerable()); + return JoinInternal(default, values.AsEnumerable()); } /// Concatenates the string representation of some specified objects. public static string Concat(IEnumerable values) { - return ConcatInternal(values); + return JoinInternal(default, values); } - static string ConcatInternal(IList values) + static string JoinInternal(ReadOnlySpan separator, IList values) { var count = values.Count; if (count == 0) @@ -317,6 +191,11 @@ static string ConcatInternal(IList values) { for (int i = 0; i < count; i++) { + if (i != 0) + { + sb.Append(separator); + } + var item = values[i]; if (typeof(T) == typeof(string)) { @@ -339,7 +218,7 @@ static string ConcatInternal(IList values) } } - static string ConcatInternal(ReadOnlySpan values) + static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) { if (values.Length == 0) { @@ -355,6 +234,11 @@ static string ConcatInternal(ReadOnlySpan values) { for (int i = 0; i < values.Length; i++) { + if (i != 0) + { + sb.Append(separator); + } + var item = values[i]; if (typeof(T) == typeof(string)) { @@ -377,13 +261,23 @@ static string ConcatInternal(ReadOnlySpan values) } } - static string ConcatInternal(IEnumerable values) + static string JoinInternal(ReadOnlySpan separator, IEnumerable values) { var sb = new Utf16ValueStringBuilder(true); try { + var isFirst = true; foreach (var item in values) { + if (!isFirst) + { + sb.Append(separator); + } + else + { + isFirst = false; + } + if (typeof(T) == typeof(string)) { var s = Unsafe.As(item); diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index ba66398e..560c92e5 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -126,181 +126,55 @@ public static string Join(string separator, IEnumerable values) return JoinInternal(separator.AsSpan(), values); } - static string JoinInternal(ReadOnlySpan separator, IList values) - { - var count = values.Count; - if (count == 0) - { - return string.Empty; - } - else if (typeof(T) == typeof(string) && count == 1) - { - return Unsafe.As(values[0]); - } - - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < count; i++) - { - if (i != 0) - { - sb.Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) - { - if (values.Length == 0) - { - return string.Empty; - } - else if (typeof(T) == typeof(string) && values.Length == 1) - { - return Unsafe.As(values[0]); - } - - var sb = new Utf16ValueStringBuilder(true); - try - { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - - static string JoinInternal(ReadOnlySpan separator, IEnumerable values) - { - var sb = new Utf16ValueStringBuilder(true); - try - { - var isFirst = true; - foreach (var item in values) - { - if (!isFirst) - { - sb.Append(separator); - } - else - { - isFirst = false; - } - - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } - - return sb.ToString(); - } - finally - { - sb.Dispose(); - } - } - /// Concatenates the string representation of some specified objects. public static string Concat(params T[] values) { - return ConcatInternal(values.AsSpan()); + return JoinInternal(default, values.AsSpan()); } /// Concatenates the string representation of some specified objects. public static string Concat(List values) { - return ConcatInternal(values); + return JoinInternal(default, values); } /// Concatenates the string representation of some specified objects. public static string Concat(ReadOnlySpan values) { - return ConcatInternal(values); + return JoinInternal(default, values); } /// Concatenates the string representation of some specified objects. public static string Concat(ICollection values) { - return ConcatInternal(values.AsEnumerable()); + return JoinInternal(default, values.AsEnumerable()); } /// Concatenates the string representation of some specified objects. public static string Concat(IList values) { - return ConcatInternal(values); + return JoinInternal(default, values); } /// Concatenates the string representation of some specified objects. public static string Concat(IReadOnlyList values) { - return ConcatInternal(values.AsEnumerable()); + return JoinInternal(default, values.AsEnumerable()); } /// Concatenates the string representation of some specified objects. public static string Concat(IReadOnlyCollection values) { - return ConcatInternal(values.AsEnumerable()); + return JoinInternal(default, values.AsEnumerable()); } /// Concatenates the string representation of some specified objects. public static string Concat(IEnumerable values) { - return ConcatInternal(values); + return JoinInternal(default, values); } - static string ConcatInternal(IList values) + static string JoinInternal(ReadOnlySpan separator, IList values) { var count = values.Count; if (count == 0) @@ -317,6 +191,11 @@ static string ConcatInternal(IList values) { for (int i = 0; i < count; i++) { + if (i != 0) + { + sb.Append(separator); + } + var item = values[i]; if (typeof(T) == typeof(string)) { @@ -339,7 +218,7 @@ static string ConcatInternal(IList values) } } - static string ConcatInternal(ReadOnlySpan values) + static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan values) { if (values.Length == 0) { @@ -355,6 +234,11 @@ static string ConcatInternal(ReadOnlySpan values) { for (int i = 0; i < values.Length; i++) { + if (i != 0) + { + sb.Append(separator); + } + var item = values[i]; if (typeof(T) == typeof(string)) { @@ -377,13 +261,23 @@ static string ConcatInternal(ReadOnlySpan values) } } - static string ConcatInternal(IEnumerable values) + static string JoinInternal(ReadOnlySpan separator, IEnumerable values) { var sb = new Utf16ValueStringBuilder(true); try { + var isFirst = true; foreach (var item in values) { + if (!isFirst) + { + sb.Append(separator); + } + else + { + isFirst = false; + } + if (typeof(T) == typeof(string)) { var s = Unsafe.As(item); From 58d200d4117650bb797d3f5fc9c0e187a2813b83 Mon Sep 17 00:00:00 2001 From: udaken Date: Fri, 3 Jul 2020 19:32:48 +0900 Subject: [PATCH 054/139] Add some manipulation methods to StringBuilder - Utf8ValueStringBuilder.Append(char value, int repeatCount) - Utf8ValueStringBuilder.Append(ReadOnlySpan value) - Utf8ValueStringBuilder.AppendLine(ReadOnlySpan value) - Utf8ValueStringBuilder.Clear() - Utf16ValueStringBuilder.Append(char value, int repeatCount) - Utf16ValueStringBuilder.AppendLine(ReadOnlySpan value) - Utf16ValueStringBuilder.Clear() --- .../ZString/Utf16ValueStringBuilder.cs | 28 ++++++++++- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 48 +++++++++++++++++-- src/ZString/Utf16ValueStringBuilder.cs | 28 ++++++++++- src/ZString/Utf8ValueStringBuilder.cs | 48 +++++++++++++++++-- 4 files changed, 142 insertions(+), 10 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index b589b3d4..3b3ff8f2 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -87,6 +87,11 @@ public void Dispose() index = 0; } + public void Clear() + { + index = 0; + } + public void TryGrow(int sizeHint) { @@ -146,6 +151,18 @@ public void Append(char value) buffer[index++] = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char value, int repeatCount) + { + if (repeatCount < 0) + { + throw new ArgumentOutOfRangeException(nameof(repeatCount)); + } + + GetSpan(repeatCount).Fill(value); + Advance(repeatCount); + } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(char value) @@ -161,6 +178,14 @@ public void Append(string value) Append(value.AsSpan()); } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string value) + { + Append(value); + AppendLine(); + } + /// Appends a contiguous region of arbitrary memory to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(ReadOnlySpan value) @@ -174,9 +199,8 @@ public void Append(ReadOnlySpan value) index += value.Length; } - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(string value) + public void AppendLine(ReadOnlySpan value) { Append(value); AppendLine(); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index eef8142a..a80f39e5 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -93,6 +93,11 @@ public void Dispose() index = 0; } + public void Clear() + { + index = 0; + } + public void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) @@ -155,6 +160,29 @@ public unsafe void Append(char value) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char value, int repeatCount) + { + if (repeatCount < 0) + { + throw new ArgumentOutOfRangeException(nameof(repeatCount)); + } + + var maxLen = UTF8NoBom.GetMaxByteCount(1); + Span utf8Bytes = stackalloc byte[maxLen]; + ReadOnlySpan chars = stackalloc char[1] { value }; + + int len = UTF8NoBom.GetBytes(chars, utf8Bytes); + + TryGrow(len * repeatCount); + + for (int i = 0; i < repeatCount; i++) + { + utf8Bytes.CopyTo(GetSpan(len)); + Advance(len); + } + } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(char value) @@ -166,6 +194,21 @@ public void AppendLine(char value) /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) + { + Append(value.AsSpan()); + } + + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string value) + { + Append(value); + AppendLine(); + } + + /// Appends a contiguous region of arbitrary memory to this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(ReadOnlySpan value) { var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); if (buffer.Length - index < maxLen) @@ -173,12 +216,11 @@ public void Append(string value) Grow(maxLen); } - index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); + index += UTF8NoBom.GetBytes(value, buffer.AsSpan(index)); } - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(string value) + public void AppendLine(ReadOnlySpan value) { Append(value); AppendLine(); diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index b589b3d4..3b3ff8f2 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -87,6 +87,11 @@ public void Dispose() index = 0; } + public void Clear() + { + index = 0; + } + public void TryGrow(int sizeHint) { @@ -146,6 +151,18 @@ public void Append(char value) buffer[index++] = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char value, int repeatCount) + { + if (repeatCount < 0) + { + throw new ArgumentOutOfRangeException(nameof(repeatCount)); + } + + GetSpan(repeatCount).Fill(value); + Advance(repeatCount); + } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(char value) @@ -161,6 +178,14 @@ public void Append(string value) Append(value.AsSpan()); } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string value) + { + Append(value); + AppendLine(); + } + /// Appends a contiguous region of arbitrary memory to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(ReadOnlySpan value) @@ -174,9 +199,8 @@ public void Append(ReadOnlySpan value) index += value.Length; } - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(string value) + public void AppendLine(ReadOnlySpan value) { Append(value); AppendLine(); diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index eef8142a..a80f39e5 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -93,6 +93,11 @@ public void Dispose() index = 0; } + public void Clear() + { + index = 0; + } + public void TryGrow(int sizeHint) { if (buffer.Length < index + sizeHint) @@ -155,6 +160,29 @@ public unsafe void Append(char value) } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char value, int repeatCount) + { + if (repeatCount < 0) + { + throw new ArgumentOutOfRangeException(nameof(repeatCount)); + } + + var maxLen = UTF8NoBom.GetMaxByteCount(1); + Span utf8Bytes = stackalloc byte[maxLen]; + ReadOnlySpan chars = stackalloc char[1] { value }; + + int len = UTF8NoBom.GetBytes(chars, utf8Bytes); + + TryGrow(len * repeatCount); + + for (int i = 0; i < repeatCount; i++) + { + utf8Bytes.CopyTo(GetSpan(len)); + Advance(len); + } + } + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AppendLine(char value) @@ -166,6 +194,21 @@ public void AppendLine(char value) /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) + { + Append(value.AsSpan()); + } + + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(string value) + { + Append(value); + AppendLine(); + } + + /// Appends a contiguous region of arbitrary memory to this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(ReadOnlySpan value) { var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); if (buffer.Length - index < maxLen) @@ -173,12 +216,11 @@ public void Append(string value) Grow(maxLen); } - index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); + index += UTF8NoBom.GetBytes(value, buffer.AsSpan(index)); } - /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AppendLine(string value) + public void AppendLine(ReadOnlySpan value) { Append(value); AppendLine(); From b735e58920c9da01ffab1d1508d26519ff394c4f Mon Sep 17 00:00:00 2001 From: udaken Date: Fri, 3 Jul 2020 20:14:23 +0900 Subject: [PATCH 055/139] Add Utf16ValueStringBuilder.Replace() --- .../Benchmarks/ReplaceBenchmark.cs | 189 ++++++++++++++++++ .../ZString/Utf16ValueStringBuilder.cs | 135 +++++++++++++ src/ZString/Utf16ValueStringBuilder.cs | 135 +++++++++++++ tests/ZString.Tests/ReplaceTest.cs | 76 +++++++ 4 files changed, 535 insertions(+) create mode 100644 sandbox/PerfBenchmark/Benchmarks/ReplaceBenchmark.cs create mode 100644 tests/ZString.Tests/ReplaceTest.cs diff --git a/sandbox/PerfBenchmark/Benchmarks/ReplaceBenchmark.cs b/sandbox/PerfBenchmark/Benchmarks/ReplaceBenchmark.cs new file mode 100644 index 00000000..ceed26b2 --- /dev/null +++ b/sandbox/PerfBenchmark/Benchmarks/ReplaceBenchmark.cs @@ -0,0 +1,189 @@ +using BenchmarkDotNet.Attributes; +using Cysharp.Text; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Formatting; + +namespace PerfBenchmark.Benchmarks +{ + [Config(typeof(BenchmarkConfig))] + public class ReplaceBenchmark + { + StringBuilder bcl; + + string text = "The quick brown fox jumped over the lazy dogs."; + string largeText; + + string guid = Guid.NewGuid().ToString(); + + readonly string[] csharpKeywords = + { + "abstract", + "as", + "async", + "await", + "base", + "bool", + "break", + "byte", + "case", + "catch", + "char", + "checked", + "class", + "const", + "continue", + "decimal", + "default", + "delegate", + "do", + "double", + "else", + "enum", + "event", + "explicit", + "extern", + "false", + "finally", + "fixed", + "float", + "for", + "foreach", + "goto", + "if", + "implicit", + "in", + "int", + "interface", + "internal", + "is", + "lock", + "long", + "namespace", + "new", + "null", + "object", + "operator", + "out", + "override", + "params", + "private", + "protected", + "public", + "readonly", + "ref", + "return", + "sbyte", + "sealed", + "short", + "sizeof", + "stackalloc", + "static", + "string", + "struct", + "switch", + "this", + "throw", + "true", + "try", + "typeof", + "uint", + "ulong", + "unchecked", + "unsafe", + "ushort", + "using", + "virtual", + "volatile", + "void", + "while", + }; + + private static string GetThisFilePath([System.Runtime.CompilerServices.CallerFilePath] string path = null) => path; + + public ReplaceBenchmark() + { + bcl = new StringBuilder(); + largeText = System.IO.File.ReadAllText(GetThisFilePath()); //read this file + if (largeText.Length < 2048) + throw new Exception(); + } + + [Benchmark] + public int ReplaceChar() + { + bcl.Clear(); + return bcl.Append(text).Replace(' ', '\n').Length; + } + + [Benchmark] + public int ZReplaceChar() + { + using var zsb = ZString.CreateStringBuilder(true); + zsb.Append(text); + zsb.Replace(' ', '\n'); + return zsb.Length; // Use Length to avoid omitting it + } + + [Benchmark] + public int ReplaceString() + { + bcl.Clear(); + return bcl.Append(text).Replace(" ", "\r\n").Length; // Use Length to avoid omitting it + } + + [Benchmark] + public int ZReplaceString() + { + using var zsb = ZString.CreateStringBuilder(true); + zsb.Append(text); + zsb.Replace(" ", "\r\n"); + return zsb.Length; // Use Length to avoid omitting it + } + + [Benchmark] + public int NotReplaced() + { + bcl.Clear(); + bcl.Append(largeText); + bcl.Replace(guid, "XXXXXX"); // GUID value should not be included in this file. + return bcl.Length; // Use Length to avoid omitting it + } + + [Benchmark] + public int ZNotReplaced() + { + using var zsb = ZString.CreateStringBuilder(true); + zsb.Append(text); + zsb.Replace(guid, "XXXXXX"); // GUID value should not be included in this file. + return zsb.Length; // Use Length to avoid omitting it + } + + [Benchmark] + public int ManyTimesReplace() + { + bcl.Clear(); + bcl.Append(largeText); + // remove all keywords + foreach (var keyword in csharpKeywords) + { + bcl.Replace(keyword, ""); + } + return bcl.Length; // Use Length to avoid omitting it + } + + [Benchmark] + public int ZManyTimesReplace() + { + using var zsb = ZString.CreateStringBuilder(true); + zsb.Append(text); + // remove all keywords + foreach (var keyword in csharpKeywords) + { + zsb.Replace(keyword, ""); + } + return zsb.Length; // Use Length to avoid omitting it + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 3b3ff8f2..9dfe664b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -227,6 +227,141 @@ public void AppendLine(T value) AppendLine(); } + /// + /// Replaces all instances of one character with another in this builder. + /// + /// The character to replace. + /// The character to replace with. + public void Replace(char oldChar, char newChar) => Replace(oldChar, newChar, 0, Length); + + /// + /// Replaces all instances of one character with another in this builder. + /// + /// The character to replace. + /// The character to replace with. + /// The index to start in this builder. + /// The number of characters to read in this builder. + public void Replace(char oldChar, char newChar, int startIndex, int count) + { + int currentLength = Length; + if ((uint)startIndex > (uint)currentLength) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || startIndex > currentLength - count) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + int endIndex = startIndex + count; + + for (int i = startIndex; i < endIndex; i++) + { + if (buffer[i] == oldChar) + { + buffer[i] = newChar; + } + } + } + + /// + /// Replaces all instances of one string with another in this builder. + /// + /// The string to replace. + /// The string to replace with. + /// + /// If is null, instances of + /// are removed from this builder. + /// + public void Replace(string oldValue, string newValue) => Replace(oldValue, newValue, 0, Length); + + /// + /// Replaces all instances of one string with another in part of this builder. + /// + /// The string to replace. + /// The string to replace with. + /// The index to start in this builder. + /// The number of characters to read in this builder. + /// + /// If is null, instances of + /// are removed from this builder. + /// + public void Replace(string oldValue, string newValue, int startIndex, int count) + { + int currentLength = Length; + + if ((uint)startIndex > (uint)currentLength) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || startIndex > currentLength - count) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (oldValue == null) + { + throw new ArgumentNullException(nameof(oldValue)); + } + + if (oldValue.Length == 0) + { + throw new ArgumentException("oldValue.Length is 0", nameof(oldValue)); + } + + newValue = newValue ?? string.Empty; + + var readOnlySpan = AsSpan(); + int endIndex = startIndex + count; + int matchCount = 0; + + for (int i = startIndex; i < endIndex; i += oldValue.Length) + { + var span = readOnlySpan.Slice(i, endIndex - i); + var pos = span.IndexOf(oldValue.AsSpan(), StringComparison.Ordinal); + if (pos == -1) + { + break; + } + i += pos; + matchCount++; + } + + if (matchCount == 0) + return; + + var newBuffer = ArrayPool.Shared.Rent(Math.Max(DefaultBufferSize, Length + (newValue.Length - oldValue.Length) * matchCount)); + + buffer.AsSpan(0, startIndex).CopyTo(newBuffer); + int newBufferIndex = startIndex; + + for (int i = startIndex; i < endIndex; i += oldValue.Length) + { + var span = readOnlySpan.Slice(i, endIndex - i); + var pos = span.IndexOf(oldValue.AsSpan(), StringComparison.Ordinal); + if (pos == -1) + { + var remain = readOnlySpan.Slice(i); + remain.CopyTo(newBuffer.AsSpan(newBufferIndex)); + newBufferIndex += remain.Length; + break; + } + readOnlySpan.Slice(i, pos).CopyTo(newBuffer.AsSpan(newBufferIndex)); + newValue.AsSpan().CopyTo(newBuffer.AsSpan(newBufferIndex + pos)); + newBufferIndex += pos + newValue.Length; + i += pos; + } + + if (buffer.Length != ThreadStaticBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + buffer = newBuffer; + index = newBufferIndex; + } + // Output /// Copy inner buffer to the destination span. diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 3b3ff8f2..9dfe664b 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -227,6 +227,141 @@ public void AppendLine(T value) AppendLine(); } + /// + /// Replaces all instances of one character with another in this builder. + /// + /// The character to replace. + /// The character to replace with. + public void Replace(char oldChar, char newChar) => Replace(oldChar, newChar, 0, Length); + + /// + /// Replaces all instances of one character with another in this builder. + /// + /// The character to replace. + /// The character to replace with. + /// The index to start in this builder. + /// The number of characters to read in this builder. + public void Replace(char oldChar, char newChar, int startIndex, int count) + { + int currentLength = Length; + if ((uint)startIndex > (uint)currentLength) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || startIndex > currentLength - count) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + int endIndex = startIndex + count; + + for (int i = startIndex; i < endIndex; i++) + { + if (buffer[i] == oldChar) + { + buffer[i] = newChar; + } + } + } + + /// + /// Replaces all instances of one string with another in this builder. + /// + /// The string to replace. + /// The string to replace with. + /// + /// If is null, instances of + /// are removed from this builder. + /// + public void Replace(string oldValue, string newValue) => Replace(oldValue, newValue, 0, Length); + + /// + /// Replaces all instances of one string with another in part of this builder. + /// + /// The string to replace. + /// The string to replace with. + /// The index to start in this builder. + /// The number of characters to read in this builder. + /// + /// If is null, instances of + /// are removed from this builder. + /// + public void Replace(string oldValue, string newValue, int startIndex, int count) + { + int currentLength = Length; + + if ((uint)startIndex > (uint)currentLength) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || startIndex > currentLength - count) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + if (oldValue == null) + { + throw new ArgumentNullException(nameof(oldValue)); + } + + if (oldValue.Length == 0) + { + throw new ArgumentException("oldValue.Length is 0", nameof(oldValue)); + } + + newValue = newValue ?? string.Empty; + + var readOnlySpan = AsSpan(); + int endIndex = startIndex + count; + int matchCount = 0; + + for (int i = startIndex; i < endIndex; i += oldValue.Length) + { + var span = readOnlySpan.Slice(i, endIndex - i); + var pos = span.IndexOf(oldValue.AsSpan(), StringComparison.Ordinal); + if (pos == -1) + { + break; + } + i += pos; + matchCount++; + } + + if (matchCount == 0) + return; + + var newBuffer = ArrayPool.Shared.Rent(Math.Max(DefaultBufferSize, Length + (newValue.Length - oldValue.Length) * matchCount)); + + buffer.AsSpan(0, startIndex).CopyTo(newBuffer); + int newBufferIndex = startIndex; + + for (int i = startIndex; i < endIndex; i += oldValue.Length) + { + var span = readOnlySpan.Slice(i, endIndex - i); + var pos = span.IndexOf(oldValue.AsSpan(), StringComparison.Ordinal); + if (pos == -1) + { + var remain = readOnlySpan.Slice(i); + remain.CopyTo(newBuffer.AsSpan(newBufferIndex)); + newBufferIndex += remain.Length; + break; + } + readOnlySpan.Slice(i, pos).CopyTo(newBuffer.AsSpan(newBufferIndex)); + newValue.AsSpan().CopyTo(newBuffer.AsSpan(newBufferIndex + pos)); + newBufferIndex += pos + newValue.Length; + i += pos; + } + + if (buffer.Length != ThreadStaticBufferSize) + { + ArrayPool.Shared.Return(buffer); + } + buffer = newBuffer; + index = newBufferIndex; + } + // Output /// Copy inner buffer to the destination span. diff --git a/tests/ZString.Tests/ReplaceTest.cs b/tests/ZString.Tests/ReplaceTest.cs new file mode 100644 index 00000000..8c1ead14 --- /dev/null +++ b/tests/ZString.Tests/ReplaceTest.cs @@ -0,0 +1,76 @@ +using Cysharp.Text; +using FluentAssertions; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public class ReplaceTest + { + [Fact] + public void ReplaceCharTest() + { + var s = new string(' ', 10); + using (var zsb = ZString.CreateStringBuilder()) + { + zsb.Append(s); + zsb.Replace(' ', '-', 2, 5); + zsb.ToString().Should().Be(new StringBuilder(s).Replace(' ', '-', 2, 5).ToString()); + } + + s = "0"; + using (var zsb = ZString.CreateStringBuilder()) + { + zsb.Append(s); + zsb.Replace('0', '1'); + zsb.ToString().Should().Be(new StringBuilder(s).Replace('0', '1').ToString()); + } + } + + [Fact] + public void ReplaceStringTest() + { + using (var zsb = ZString.CreateStringBuilder(notNested: true)) + { + var text = "bra bra BRA bra bra"; + zsb.Append(text); + var bcl = new StringBuilder(text); + + zsb.Replace("bra", null, 1, text.Length - 2); + bcl.Replace("bra", null, 1, text.Length - 2); + + // "bra BRA bra" + zsb.ToString().Should().Be(bcl.ToString()); + } + + using (var zsb = ZString.CreateStringBuilder()) + { + var text = "The quick brown dog jumps over the lazy cat."; + zsb.Append(text); + var bcl = new StringBuilder(text); + + // All "cat" -> "dog" + zsb.Replace("cat", "dog"); + bcl.Replace("cat", "dog"); + zsb.ToString().Should().Be(bcl.ToString()); + + // Some "dog" -> "fox" + zsb.Replace("dog", "fox", 15, 20); + bcl.Replace("dog", "fox", 15, 20); + zsb.ToString().Should().Be(bcl.ToString()); + } + } + + [Fact] + public void NotMatchTest() + { + using (var zsb = ZString.CreateStringBuilder(notNested: true)) + { + var text = "The quick brown dog jumps over the lazy cat."; + zsb.Append(text); + zsb.Replace("pig", "dog"); + zsb.ToString().Should().Be(text); + } + } + } +} From c5fc107183ab508752c61fdd473454c37b6aaf73 Mon Sep 17 00:00:00 2001 From: udaken Date: Fri, 3 Jul 2020 20:45:59 +0900 Subject: [PATCH 056/139] Add Utf16ValueStringBuilder.Remove(int startIndex, int length) --- .../ZString/Utf16ValueStringBuilder.cs | 38 +++++++++++++ src/ZString/Utf16ValueStringBuilder.cs | 38 +++++++++++++ tests/ZString.Tests/RemoveTest.cs | 53 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 tests/ZString.Tests/RemoveTest.cs diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 9dfe664b..57f91ad2 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -362,6 +362,44 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) index = newBufferIndex; } + /// + /// Removes a range of characters from this builder. + /// + /// + /// This method does not reduce the capacity of this builder. + /// + public void Remove(int startIndex, int length) + { + if (length < 0) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + if (startIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (length > Length - startIndex) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + if (Length == length && startIndex == 0) + { + index = 0; + return; + } + + if (length == 0) + { + return; + } + + buffer.AsSpan(startIndex + length).CopyTo(buffer.AsSpan(startIndex)); + index -= length; + } + // Output /// Copy inner buffer to the destination span. diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 9dfe664b..57f91ad2 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -362,6 +362,44 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) index = newBufferIndex; } + /// + /// Removes a range of characters from this builder. + /// + /// + /// This method does not reduce the capacity of this builder. + /// + public void Remove(int startIndex, int length) + { + if (length < 0) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + if (startIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (length > Length - startIndex) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + if (Length == length && startIndex == 0) + { + index = 0; + return; + } + + if (length == 0) + { + return; + } + + buffer.AsSpan(startIndex + length).CopyTo(buffer.AsSpan(startIndex)); + index -= length; + } + // Output /// Copy inner buffer to the destination span. diff --git a/tests/ZString.Tests/RemoveTest.cs b/tests/ZString.Tests/RemoveTest.cs new file mode 100644 index 00000000..d243945b --- /dev/null +++ b/tests/ZString.Tests/RemoveTest.cs @@ -0,0 +1,53 @@ +using Cysharp.Text; +using FluentAssertions; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public class RemoveTest + { + [Fact] + public void RemovePart() + { + string str = "The quick brown fox jumps over the lazy dog."; + using var zsb = ZString.CreateStringBuilder(); + zsb.Append(str); + var bcl = new StringBuilder(str); + + // Remove "brown " + zsb.Remove(10, 6); + bcl.Remove(10, 6); + + zsb.ToString().Should().Be(bcl.ToString()); + } + + [Fact] + public void RemoveAll() + { + string str = "The quick brown fox jumps over the lazy dog."; + using var zsb = ZString.CreateStringBuilder(); + zsb.Append(str); + var bcl = new StringBuilder(str); + + zsb.Remove(0, str.Length); + bcl.Remove(0, str.Length); + + zsb.ToString().Should().Be(bcl.ToString()); + } + + [Fact] + public void RemoveTail() + { + string str = "foo,bar,baz"; + using var zsb = ZString.CreateStringBuilder(); + zsb.Append(str); + var bcl = new StringBuilder(str); + + zsb.Remove(7, 4); + bcl.Remove(7, 4); + + zsb.ToString().Should().Be(bcl.ToString()); + } + } +} From 6b153146b0e644cd43f25634b30451cc6d639c34 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 4 Jul 2020 09:19:05 +0900 Subject: [PATCH 057/139] Fix NetCore2Tests --- tests/ZString.Tests/RemoveTest.cs | 44 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/tests/ZString.Tests/RemoveTest.cs b/tests/ZString.Tests/RemoveTest.cs index d243945b..bb95bf37 100644 --- a/tests/ZString.Tests/RemoveTest.cs +++ b/tests/ZString.Tests/RemoveTest.cs @@ -11,43 +11,49 @@ public class RemoveTest public void RemovePart() { string str = "The quick brown fox jumps over the lazy dog."; - using var zsb = ZString.CreateStringBuilder(); - zsb.Append(str); - var bcl = new StringBuilder(str); + using (var zsb = ZString.CreateStringBuilder()) + { + zsb.Append(str); + var bcl = new StringBuilder(str); - // Remove "brown " - zsb.Remove(10, 6); - bcl.Remove(10, 6); + // Remove "brown " + zsb.Remove(10, 6); + bcl.Remove(10, 6); - zsb.ToString().Should().Be(bcl.ToString()); + zsb.ToString().Should().Be(bcl.ToString()); + } } [Fact] public void RemoveAll() { string str = "The quick brown fox jumps over the lazy dog."; - using var zsb = ZString.CreateStringBuilder(); - zsb.Append(str); - var bcl = new StringBuilder(str); + using (var zsb = ZString.CreateStringBuilder()) + { + zsb.Append(str); + var bcl = new StringBuilder(str); - zsb.Remove(0, str.Length); - bcl.Remove(0, str.Length); + zsb.Remove(0, str.Length); + bcl.Remove(0, str.Length); - zsb.ToString().Should().Be(bcl.ToString()); + zsb.ToString().Should().Be(bcl.ToString()); + } } [Fact] public void RemoveTail() { string str = "foo,bar,baz"; - using var zsb = ZString.CreateStringBuilder(); - zsb.Append(str); - var bcl = new StringBuilder(str); + using (var zsb = ZString.CreateStringBuilder()) + { + zsb.Append(str); + var bcl = new StringBuilder(str); - zsb.Remove(7, 4); - bcl.Remove(7, 4); + zsb.Remove(7, 4); + bcl.Remove(7, 4); - zsb.ToString().Should().Be(bcl.ToString()); + zsb.ToString().Should().Be(bcl.ToString()); + } } } } From a9b279becd49d827da31016bbd3df707d60466d4 Mon Sep 17 00:00:00 2001 From: udaken Date: Sun, 5 Jul 2020 00:25:21 +0900 Subject: [PATCH 058/139] Remove duplicated codes in t4 file --- .../Assets/Scripts/ZString/PreparedFormat.cs | 3 +- .../Utf16ValueStringBuilder.AppendFormat.cs | 7 +-- ...alueStringBuilder.SpanFormattableAppend.cs | 2 +- .../Utf8ValueStringBuilder.CreateFormatter.cs | 11 ++--- .../Assets/Scripts/ZString/ZString.Format.cs | 3 +- .../Scripts/ZString/ZString.Utf8Format.cs | 3 +- src/ZString/PreparedFormat.cs | 3 +- src/ZString/PreparedFormat.tt | 21 +-------- src/ZString/T4Common.t4 | 44 +++++++++++++++++++ .../Utf16ValueStringBuilder.AppendFormat.cs | 7 +-- .../Utf16ValueStringBuilder.AppendFormat.tt | 17 ++----- ...alueStringBuilder.SpanFormattableAppend.cs | 2 +- ...alueStringBuilder.SpanFormattableAppend.tt | 24 +--------- .../Utf8ValueStringBuilder.AppendFormat.tt | 16 ++----- .../Utf8ValueStringBuilder.CreateFormatter.cs | 11 ++--- .../Utf8ValueStringBuilder.CreateFormatter.tt | 22 +--------- ...alueStringBuilder.SpanFormattableAppend.tt | 24 +--------- src/ZString/ZString.Concat.tt | 15 +------ src/ZString/ZString.Format.cs | 3 +- src/ZString/ZString.Format.tt | 20 +-------- src/ZString/ZString.Prepare.tt | 9 +--- src/ZString/ZString.Utf8Format.cs | 3 +- src/ZString/ZString.Utf8Format.tt | 15 +------ src/ZString/ZString.csproj | 9 ++++ 24 files changed, 108 insertions(+), 186 deletions(-) create mode 100644 src/ZString/T4Common.t4 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs index 4759b589..c5c66d2a 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs @@ -1,4 +1,5 @@ -using System; + +using System; using System.Text; using System.Buffers; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 95caf7b4..f023a822 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -1,4 +1,5 @@ -using System; + +using System; namespace Cysharp.Text { @@ -17,7 +18,7 @@ public void AppendFormat(string format, T1 arg1) { throw new FormatException("invalid format"); } - + if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; @@ -2973,4 +2974,4 @@ public void AppendFormat((System.Double x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(System.Guid)) - { - return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } if (type == typeof(System.Int16)) { return new TryFormat((System.Int16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); @@ -68,6 +65,10 @@ static object CreateFormatter(Type type) { return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } + if (type == typeof(System.Guid)) + { + return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } return null; } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs index 294862ca..8eb89a1b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs @@ -1,4 +1,5 @@ -using System.Runtime.CompilerServices; + +using System.Runtime.CompilerServices; namespace Cysharp.Text { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs index dcf7f395..60d49dcf 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs @@ -1,4 +1,5 @@ -using System.Runtime.CompilerServices; + +using System.Runtime.CompilerServices; using System.Buffers; using System; diff --git a/src/ZString/PreparedFormat.cs b/src/ZString/PreparedFormat.cs index 4759b589..c5c66d2a 100644 --- a/src/ZString/PreparedFormat.cs +++ b/src/ZString/PreparedFormat.cs @@ -1,4 +1,5 @@ -using System; + +using System; using System.Text; using System.Buffers; diff --git a/src/ZString/PreparedFormat.tt b/src/ZString/PreparedFormat.tt index df6e15d0..edfd098f 100644 --- a/src/ZString/PreparedFormat.tt +++ b/src/ZString/PreparedFormat.tt @@ -4,24 +4,7 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); - } - - static string CreateParameterNames(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + (x + 1))); - } - - string[] utfTypes = new [] { "Utf16", "Utf8" }; -#> +<#@ include file="T4Common.t4" once="true" #> using System; using System.Text; using System.Buffers; @@ -29,7 +12,7 @@ using System.Buffers; namespace Cysharp.Text { <# foreach(var utf in utfTypes) { var isUtf16 = (utf == "Utf16"); #> -<# for(var i = 1; i <= 16; i++) { #> +<# for(var i = 1; i <= TypeParamMax; i++) { #> public sealed partial class <#= utf #>PreparedFormat<<#= CreateTypeArgument(i) #>> { public string FormatString { get; } diff --git a/src/ZString/T4Common.t4 b/src/ZString/T4Common.t4 new file mode 100644 index 00000000..8ef1a1f4 --- /dev/null +++ b/src/ZString/T4Common.t4 @@ -0,0 +1,44 @@ +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<# + const int TypeParamMax = 16; + + string[] utfTypes = new [] { "Utf16", "Utf8" }; + + static string CreateTypeArgument(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); + } + + static string CreateParameters(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); + } + + static string CreateParameterNames(int i) + { + return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + (x + 1))); + } + + Type[] spanFormattables = new Type[] + { + typeof(Byte), + typeof(DateTime), + typeof(DateTimeOffset), + typeof(Decimal), + typeof(Double), + typeof(Int16), + typeof(Int32), + typeof(Int64), + typeof(SByte), + typeof(Single), + typeof(TimeSpan), + typeof(UInt16), + typeof(UInt32), + typeof(UInt64), + typeof(Guid), + // typeof(Version), + }; +#> \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 95caf7b4..f023a822 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -1,4 +1,5 @@ -using System; + +using System; namespace Cysharp.Text { @@ -17,7 +18,7 @@ public void AppendFormat(string format, T1 arg1) { throw new FormatException("invalid format"); } - + if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; @@ -2973,4 +2974,4 @@ public void AppendFormat <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); - } - -#> +<#@ include file="../T4Common.t4" once="true" #> using System; namespace Cysharp.Text { public partial struct Utf16ValueStringBuilder { -<# for(var i = 1; i <= 16; i++) { #> +<# for(var i = 1; i <= TypeParamMax; i++) { #> /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { @@ -115,4 +104,4 @@ namespace Cysharp.Text <# } #> } -} \ No newline at end of file +} diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index 0f07d69a..bdf6e179 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -681,4 +681,4 @@ public void AppendLine(System.Guid value, string format) AppendLine(); } } -} \ No newline at end of file +} diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt index d48abf68..0189dc34 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt @@ -4,27 +4,7 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - var spanFormattables = new Type[] - { - typeof(Byte), - typeof(DateTime), - typeof(DateTimeOffset), - typeof(Decimal), - typeof(Double), - typeof(Int16), - typeof(Int32), - typeof(Int64), - typeof(SByte), - typeof(Single), - typeof(TimeSpan), - typeof(UInt16), - typeof(UInt32), - typeof(UInt64), - typeof(Guid), - // typeof(Version), - }; -#> +<#@ include file="../T4Common.t4" once="true" #> using System; using System.Runtime.CompilerServices; @@ -80,4 +60,4 @@ namespace Cysharp.Text } <# } #> } -} \ No newline at end of file +} diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt index a9ef706c..ec591ee3 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt @@ -3,18 +3,8 @@ <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> +<#@ include file="../T4Common.t4" once="true" #> <#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); - } -#> using System; using System.Buffers; @@ -22,7 +12,7 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder { -<# for(var i = 1; i <= 16; i++) { #> +<# for(var i = 1; i <= TypeParamMax; i++) { #> /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { @@ -111,4 +101,4 @@ namespace Cysharp.Text <# } #> } -} \ No newline at end of file +} diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index 7511ae11..20071aaf 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -1,4 +1,5 @@ -using System; + +using System; using System.Buffers; using System.Buffers.Text; @@ -28,10 +29,6 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Double x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } - if (type == typeof(System.Guid)) - { - return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); - } if (type == typeof(System.Int16)) { return new TryFormat((System.Int16 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); @@ -68,6 +65,10 @@ static object CreateFormatter(Type type) { return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } + if (type == typeof(System.Guid)) + { + return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } return null; } diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt index b82d6ef9..7bd5f0af 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt @@ -4,27 +4,7 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - var spanFormattables = new Type[] - { - typeof(Byte), - typeof(DateTime), - typeof(DateTimeOffset), - typeof(Decimal), - typeof(Double), - typeof(Guid), - typeof(Int16), - typeof(Int32), - typeof(Int64), - typeof(SByte), - typeof(Single), - typeof(TimeSpan), - typeof(UInt16), - typeof(UInt32), - typeof(UInt64), - // typeof(Version), - }; -#> +<#@ include file="../T4Common.t4" once="true" #> using System; using System.Buffers; using System.Buffers.Text; diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt index 171af036..7bc13892 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt @@ -4,27 +4,7 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - var spanFormattables = new Type[] - { - typeof(Byte), - typeof(DateTime), - typeof(DateTimeOffset), - typeof(Decimal), - typeof(Double), - typeof(Int16), - typeof(Int32), - typeof(Int64), - typeof(SByte), - typeof(Single), - typeof(TimeSpan), - typeof(UInt16), - typeof(UInt32), - typeof(UInt64), - typeof(Guid), - // typeof(Version), - }; -#> +<#@ include file="../T4Common.t4" once="true" #> using System; using System.Buffers; using System.Buffers.Text; @@ -82,4 +62,4 @@ namespace Cysharp.Text } <# } #> } -} \ No newline at end of file +} diff --git a/src/ZString/ZString.Concat.tt b/src/ZString/ZString.Concat.tt index aac7d159..4c5f0557 100644 --- a/src/ZString/ZString.Concat.tt +++ b/src/ZString/ZString.Concat.tt @@ -4,25 +4,14 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); - } - -#> +<#@ include file="T4Common.t4" once="true" #> using System.Runtime.CompilerServices; namespace Cysharp.Text { public static partial class ZString { -<# for(var i = 1; i <= 16; i++) { #> +<# for(var i = 1; i <= TypeParamMax; i++) { #> /// Concatenates the string representation of some specified objects. public static string Concat<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) { diff --git a/src/ZString/ZString.Format.cs b/src/ZString/ZString.Format.cs index 294862ca..8eb89a1b 100644 --- a/src/ZString/ZString.Format.cs +++ b/src/ZString/ZString.Format.cs @@ -1,4 +1,5 @@ -using System.Runtime.CompilerServices; + +using System.Runtime.CompilerServices; namespace Cysharp.Text { diff --git a/src/ZString/ZString.Format.tt b/src/ZString/ZString.Format.tt index e6449f9d..5d10054f 100644 --- a/src/ZString/ZString.Format.tt +++ b/src/ZString/ZString.Format.tt @@ -4,30 +4,14 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); - } - - - static string CreateParameterNames(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "arg" + (x + 1))); - } -#> +<#@ include file="T4Common.t4" once="true" #> using System.Runtime.CompilerServices; namespace Cysharp.Text { public static partial class ZString { -<# for(var i = 1; i <= 16; i++) { #> +<# for(var i = 1; i <= TypeParamMax; i++) { #> /// Replaces one or more format items in a string with the string representation of some specified objects. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string Format<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) diff --git a/src/ZString/ZString.Prepare.tt b/src/ZString/ZString.Prepare.tt index d3f4f72c..ac962cb3 100644 --- a/src/ZString/ZString.Prepare.tt +++ b/src/ZString/ZString.Prepare.tt @@ -4,19 +4,14 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); - } -#> +<#@ include file="T4Common.t4" once="true" #> using System.Runtime.CompilerServices; namespace Cysharp.Text { public static partial class ZString { -<# for(var i = 1; i <= 16; i++) { #> +<# for(var i = 1; i <= TypeParamMax; i++) { #> /// Prepare string format to avoid parse template in each operation. public static Utf16PreparedFormat<<#= CreateTypeArgument(i) #>> PrepareUtf16<<#= CreateTypeArgument(i) #>>(string format) { diff --git a/src/ZString/ZString.Utf8Format.cs b/src/ZString/ZString.Utf8Format.cs index dcf7f395..60d49dcf 100644 --- a/src/ZString/ZString.Utf8Format.cs +++ b/src/ZString/ZString.Utf8Format.cs @@ -1,4 +1,5 @@ -using System.Runtime.CompilerServices; + +using System.Runtime.CompilerServices; using System.Buffers; using System; diff --git a/src/ZString/ZString.Utf8Format.tt b/src/ZString/ZString.Utf8Format.tt index a7b284e4..5ca32f76 100644 --- a/src/ZString/ZString.Utf8Format.tt +++ b/src/ZString/ZString.Utf8Format.tt @@ -4,18 +4,7 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> -<# - static string CreateTypeArgument(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1))); - } - - static string CreateParameters(int i) - { - return string.Join(", ", Enumerable.Range(0, i).Select(x => "T" + (x + 1) + " arg" + (x + 1))); - } - -#> +<#@ include file="T4Common.t4" once="true" #> using System.Runtime.CompilerServices; using System.Buffers; using System; @@ -24,7 +13,7 @@ namespace Cysharp.Text { public static partial class ZString { -<# for(var i = 1; i <= 16; i++) { #> +<# for(var i = 1; i <= TypeParamMax; i++) { #> /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format<<#= CreateTypeArgument(i) #>>(IBufferWriter bufferWriter, string format, <#= CreateParameters(i) #>) { diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index a9ce33aa..ced7c2ff 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -35,6 +35,10 @@ TextTemplatingFileGenerator PreparedFormat.cs + + TextTemplatingFileGenerator + StringBuilderExtension.cs + TextTemplatingFileGenerator TextMeshProExtensions.cs @@ -95,6 +99,11 @@ True PreparedFormat.tt + + True + True + StringBuilderExtension.tt + True True From 7a7c2f4e3997e73484c6fad023a6a09900e0dedf Mon Sep 17 00:00:00 2001 From: udaken Date: Sun, 5 Jul 2020 12:39:34 +0900 Subject: [PATCH 059/139] Make throw NestedStringBuilderCreationException on nested StringBuilder creation. --- .../NestedStringBuilderCreationException.cs | 22 ++++ .../ZString/Utf16ValueStringBuilder.cs | 20 +++ .../Scripts/ZString/Utf8ValueStringBuilder.cs | 20 +++ .../NestedStringBuilderCreationException.cs | 22 ++++ src/ZString/Utf16ValueStringBuilder.cs | 20 +++ src/ZString/Utf8ValueStringBuilder.cs | 20 +++ tests/ZString.Tests/NestedStringBuilder.cs | 123 ++++++++++++++++++ 7 files changed, 247 insertions(+) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs create mode 100644 src/ZString/NestedStringBuilderCreationException.cs create mode 100644 tests/ZString.Tests/NestedStringBuilder.cs diff --git a/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs b/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs new file mode 100644 index 00000000..4f263d94 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs @@ -0,0 +1,22 @@ +using System; + +namespace Cysharp.Text +{ + // Currently, this class is internals. + internal class NestedStringBuilderCreationException : InvalidOperationException + { + private NestedStringBuilderCreationException() + { + } + + internal protected NestedStringBuilderCreationException(string typeName, string extraMessage = "") + : base($"A nested call with `notNested: true`, or Either You forgot to call {typeName}.Dispose() of in the past.{extraMessage}") + { + } + + internal protected NestedStringBuilderCreationException(string message, Exception innerException) : base(message, innerException) + { + } + + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index b589b3d4..ff483a36 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -37,8 +37,12 @@ static Utf16ValueStringBuilder() [ThreadStatic] static char[] scratchBuffer; + [ThreadStatic] + internal static bool scratchBufferUsed; + char[] buffer; int index; + bool disposeImmediately; /// Length of written buffer. public int Length => index; @@ -52,6 +56,11 @@ static Utf16ValueStringBuilder() [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf16ValueStringBuilder(bool disposeImmediately) { + if (disposeImmediately && scratchBufferUsed) + { + ThrowNestedException(); + } + char[] buf; if (disposeImmediately) { @@ -60,6 +69,7 @@ public Utf16ValueStringBuilder(bool disposeImmediately) { buf = scratchBuffer = new char[ThreadStaticBufferSize]; } + scratchBufferUsed = true; } else { @@ -68,6 +78,7 @@ public Utf16ValueStringBuilder(bool disposeImmediately) buffer = buf; index = 0; + this.disposeImmediately = disposeImmediately; } /// @@ -85,6 +96,10 @@ public void Dispose() } buffer = null; index = 0; + if (disposeImmediately) + { + scratchBufferUsed = false; + } } public void TryGrow(int sizeHint) @@ -270,6 +285,11 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + static void ThrowNestedException() + { + throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); + } + /// /// Register custom formatter /// diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index eef8142a..3bc7e35b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -40,8 +40,12 @@ static Utf8ValueStringBuilder() [ThreadStatic] static byte[] scratchBuffer; + [ThreadStatic] + internal static bool scratchBufferUsed; + byte[] buffer; int index; + bool disposeImmediately; /// Length of written buffer. public int Length => index; @@ -58,6 +62,11 @@ static Utf8ValueStringBuilder() [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf8ValueStringBuilder(bool disposeImmediately) { + if (disposeImmediately && scratchBufferUsed) + { + ThrowNestedException(); + } + byte[] buf; if (disposeImmediately) { @@ -66,6 +75,7 @@ public Utf8ValueStringBuilder(bool disposeImmediately) { buf = scratchBuffer = new byte[ThreadStaticBufferSize]; } + scratchBufferUsed = true; } else { @@ -74,6 +84,7 @@ public Utf8ValueStringBuilder(bool disposeImmediately) buffer = buf; index = 0; + this.disposeImmediately = disposeImmediately; } /// @@ -91,6 +102,10 @@ public void Dispose() } buffer = null; index = 0; + if (disposeImmediately) + { + scratchBufferUsed = false; + } } public void TryGrow(int sizeHint) @@ -286,6 +301,11 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + static void ThrowNestedException() + { + throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); + } + /// /// Register custom formatter /// diff --git a/src/ZString/NestedStringBuilderCreationException.cs b/src/ZString/NestedStringBuilderCreationException.cs new file mode 100644 index 00000000..4f263d94 --- /dev/null +++ b/src/ZString/NestedStringBuilderCreationException.cs @@ -0,0 +1,22 @@ +using System; + +namespace Cysharp.Text +{ + // Currently, this class is internals. + internal class NestedStringBuilderCreationException : InvalidOperationException + { + private NestedStringBuilderCreationException() + { + } + + internal protected NestedStringBuilderCreationException(string typeName, string extraMessage = "") + : base($"A nested call with `notNested: true`, or Either You forgot to call {typeName}.Dispose() of in the past.{extraMessage}") + { + } + + internal protected NestedStringBuilderCreationException(string message, Exception innerException) : base(message, innerException) + { + } + + } +} diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index b589b3d4..ff483a36 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -37,8 +37,12 @@ static Utf16ValueStringBuilder() [ThreadStatic] static char[] scratchBuffer; + [ThreadStatic] + internal static bool scratchBufferUsed; + char[] buffer; int index; + bool disposeImmediately; /// Length of written buffer. public int Length => index; @@ -52,6 +56,11 @@ static Utf16ValueStringBuilder() [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf16ValueStringBuilder(bool disposeImmediately) { + if (disposeImmediately && scratchBufferUsed) + { + ThrowNestedException(); + } + char[] buf; if (disposeImmediately) { @@ -60,6 +69,7 @@ public Utf16ValueStringBuilder(bool disposeImmediately) { buf = scratchBuffer = new char[ThreadStaticBufferSize]; } + scratchBufferUsed = true; } else { @@ -68,6 +78,7 @@ public Utf16ValueStringBuilder(bool disposeImmediately) buffer = buf; index = 0; + this.disposeImmediately = disposeImmediately; } /// @@ -85,6 +96,10 @@ public void Dispose() } buffer = null; index = 0; + if (disposeImmediately) + { + scratchBufferUsed = false; + } } public void TryGrow(int sizeHint) @@ -270,6 +285,11 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + static void ThrowNestedException() + { + throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); + } + /// /// Register custom formatter /// diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index eef8142a..3bc7e35b 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -40,8 +40,12 @@ static Utf8ValueStringBuilder() [ThreadStatic] static byte[] scratchBuffer; + [ThreadStatic] + internal static bool scratchBufferUsed; + byte[] buffer; int index; + bool disposeImmediately; /// Length of written buffer. public int Length => index; @@ -58,6 +62,11 @@ static Utf8ValueStringBuilder() [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf8ValueStringBuilder(bool disposeImmediately) { + if (disposeImmediately && scratchBufferUsed) + { + ThrowNestedException(); + } + byte[] buf; if (disposeImmediately) { @@ -66,6 +75,7 @@ public Utf8ValueStringBuilder(bool disposeImmediately) { buf = scratchBuffer = new byte[ThreadStaticBufferSize]; } + scratchBufferUsed = true; } else { @@ -74,6 +84,7 @@ public Utf8ValueStringBuilder(bool disposeImmediately) buffer = buf; index = 0; + this.disposeImmediately = disposeImmediately; } /// @@ -91,6 +102,10 @@ public void Dispose() } buffer = null; index = 0; + if (disposeImmediately) + { + scratchBufferUsed = false; + } } public void TryGrow(int sizeHint) @@ -286,6 +301,11 @@ void ThrowFormatException() throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + static void ThrowNestedException() + { + throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); + } + /// /// Register custom formatter /// diff --git a/tests/ZString.Tests/NestedStringBuilder.cs b/tests/ZString.Tests/NestedStringBuilder.cs new file mode 100644 index 00000000..8a9074dd --- /dev/null +++ b/tests/ZString.Tests/NestedStringBuilder.cs @@ -0,0 +1,123 @@ +using Cysharp.Text; +using FluentAssertions; +using FluentAssertions.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public class NestedStringBuilder + { + [Fact] + public void NotNestedUtf16() + { + using (_ = ZString.CreateStringBuilder(true)) + { + } + using (_ = ZString.CreateStringBuilder(false)) + { + using (_ = ZString.CreateStringBuilder(true)) + { + using (_ = ZString.CreateStringBuilder(false)) + { + } + } + } + } + + [Fact] + public void NestedUtf16() + { + using (_ = ZString.CreateStringBuilder(true)) + { + using (_ = ZString.CreateStringBuilder(false)) + { + Assert.Throws(() => + { + using (_ = ZString.CreateStringBuilder(true)) + { + } + } + ); + } + } + } + + [Fact] + public void NotDisposedUtf16() + { + { + _ = ZString.CreateStringBuilder(true); + } + { + Assert.Throws(() => + { + using (_ = ZString.CreateStringBuilder(true)) + { + } + } + ); + } + Utf16ValueStringBuilder.scratchBufferUsed.IsSameOrEqualTo(true); + Utf16ValueStringBuilder.scratchBufferUsed = false; + } + + [Fact] + public void NotNestedUtf8() + { + using (_ = ZString.CreateUtf8StringBuilder(true)) + { + } + using (_ = ZString.CreateUtf8StringBuilder(false)) + { + using (_ = ZString.CreateUtf8StringBuilder(true)) + { + using (_ = ZString.CreateUtf8StringBuilder(false)) + { + } + } + } + } + + [Fact] + public void NestedUtf8() + { + using (_ = ZString.CreateUtf8StringBuilder(true)) + { + using (_ = ZString.CreateUtf8StringBuilder(false)) + { + Assert.Throws(() => + { + using (_ = ZString.CreateUtf8StringBuilder(true)) + { + } + } + ); + } + } + } + + [Fact] + public void NotDisposedUtf8() + { + { + _ = ZString.CreateUtf8StringBuilder(true); + } + { + Assert.Throws(() => + { + using (_ = ZString.CreateUtf8StringBuilder(true)) + { + } + } + ); + } + Utf8ValueStringBuilder.scratchBufferUsed.IsSameOrEqualTo(true); + Utf8ValueStringBuilder.scratchBufferUsed = false; + } + + } +} From 94f69db23547ade2e02dd61d9fefa33dd42f65bc Mon Sep 17 00:00:00 2001 From: udaken Date: Mon, 6 Jul 2020 00:51:00 +0900 Subject: [PATCH 060/139] Update Documentation comments --- .../Scripts/ZString/Utf16ValueStringBuilder.cs | 10 ++++++++++ .../Scripts/ZString/Utf8ValueStringBuilder.cs | 10 ++++++++++ .../Assets/Scripts/ZString/ZString.cs | 14 ++++++++++++++ src/ZString/Utf16ValueStringBuilder.cs | 10 ++++++++++ src/ZString/Utf8ValueStringBuilder.cs | 10 ++++++++++ src/ZString/ZString.cs | 14 ++++++++++++++ 6 files changed, 68 insertions(+) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index ff483a36..0d927100 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -53,6 +53,16 @@ static Utf16ValueStringBuilder() /// Get the written buffer data. public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + /// + /// Initializes a new instance + /// + /// + /// If true uses thread-static buffer that is faster but must return immediately. + /// + /// + /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateStringBuilder(notNested: true) is nested. + /// See the README.md + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf16ValueStringBuilder(bool disposeImmediately) { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 3bc7e35b..e3f2d56e 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -59,6 +59,16 @@ static Utf8ValueStringBuilder() /// Get the written buffer data. public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + /// + /// Initializes a new instance + /// + /// + /// If true uses thread-static buffer that is faster but must return immediately. + /// + /// + /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. + /// See the README.md + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf8ValueStringBuilder(bool disposeImmediately) { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 5f18008a..a05d8953 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -23,12 +23,26 @@ public static Utf8ValueStringBuilder CreateUtf8StringBuilder() } /// Create the Utf8(`Span[byte]`) StringBuilder. + /// + /// If true uses thread-static buffer that is faster but must return immediately. + /// + /// + /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. + /// See the README.md + /// public static Utf16ValueStringBuilder CreateStringBuilder(bool notNested) { return new Utf16ValueStringBuilder(notNested); } /// Create the Utf8(`Span[byte]`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. + /// + /// If true uses thread-static buffer that is faster but must return immediately. + /// + /// + /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. + /// See the README.md + /// public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) { return new Utf8ValueStringBuilder(notNested); diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index ff483a36..0d927100 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -53,6 +53,16 @@ static Utf16ValueStringBuilder() /// Get the written buffer data. public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + /// + /// Initializes a new instance + /// + /// + /// If true uses thread-static buffer that is faster but must return immediately. + /// + /// + /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateStringBuilder(notNested: true) is nested. + /// See the README.md + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf16ValueStringBuilder(bool disposeImmediately) { diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 3bc7e35b..e3f2d56e 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -59,6 +59,16 @@ static Utf8ValueStringBuilder() /// Get the written buffer data. public ArraySegment AsArraySegment() => new ArraySegment(buffer, 0, index); + /// + /// Initializes a new instance + /// + /// + /// If true uses thread-static buffer that is faster but must return immediately. + /// + /// + /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. + /// See the README.md + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Utf8ValueStringBuilder(bool disposeImmediately) { diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 5f18008a..a05d8953 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -23,12 +23,26 @@ public static Utf8ValueStringBuilder CreateUtf8StringBuilder() } /// Create the Utf8(`Span[byte]`) StringBuilder. + /// + /// If true uses thread-static buffer that is faster but must return immediately. + /// + /// + /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. + /// See the README.md + /// public static Utf16ValueStringBuilder CreateStringBuilder(bool notNested) { return new Utf16ValueStringBuilder(notNested); } /// Create the Utf8(`Span[byte]`) StringBuilder, when true uses thread-static buffer that is faster but must return immediately. + /// + /// If true uses thread-static buffer that is faster but must return immediately. + /// + /// + /// This exception is thrown when new StringBuilder(disposeImmediately: true) or ZString.CreateUtf8StringBuilder(notNested: true) is nested. + /// See the README.md + /// public static Utf8ValueStringBuilder CreateUtf8StringBuilder(bool notNested) { return new Utf8ValueStringBuilder(notNested); From 4f9634d88e0eef584ce50e225626f5793c758bba Mon Sep 17 00:00:00 2001 From: udaken Date: Mon, 6 Jul 2020 02:34:13 +0900 Subject: [PATCH 061/139] some changes --- .../ZString/Utf16ValueStringBuilder.cs | 51 ++++++++++++------- src/ZString/Utf16ValueStringBuilder.cs | 51 ++++++++++++------- tests/ZString.Tests/ReplaceTest.cs | 13 +++++ 3 files changed, 79 insertions(+), 36 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 57f91ad2..c31bd53b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -227,6 +227,14 @@ public void AppendLine(T value) AppendLine(); } + static class ExceptionUtil + { + public static void ThrowArgumentOutOfRangeException(string paramName) + { + throw new ArgumentOutOfRangeException(paramName); + } + } + /// /// Replaces all instances of one character with another in this builder. /// @@ -246,12 +254,12 @@ public void Replace(char oldChar, char newChar, int startIndex, int count) int currentLength = Length; if ((uint)startIndex > (uint)currentLength) { - throw new ArgumentOutOfRangeException(nameof(startIndex)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); } if (count < 0 || startIndex > currentLength - count) { - throw new ArgumentOutOfRangeException(nameof(count)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); } int endIndex = startIndex + count; @@ -275,6 +283,8 @@ public void Replace(char oldChar, char newChar, int startIndex, int count) /// are removed from this builder. /// public void Replace(string oldValue, string newValue) => Replace(oldValue, newValue, 0, Length); + + public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue) => Replace(oldValue, newValue, 0, Length); /// /// Replaces all instances of one string with another in part of this builder. @@ -288,22 +298,27 @@ public void Replace(char oldChar, char newChar, int startIndex, int count) /// are removed from this builder. /// public void Replace(string oldValue, string newValue, int startIndex, int count) + { + if (oldValue == null) + { + throw new ArgumentNullException(nameof(oldValue)); + } + + Replace(oldValue.AsSpan(), newValue.AsSpan(), startIndex, count); + } + + public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue, int startIndex, int count) { int currentLength = Length; if ((uint)startIndex > (uint)currentLength) { - throw new ArgumentOutOfRangeException(nameof(startIndex)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); } if (count < 0 || startIndex > currentLength - count) { - throw new ArgumentOutOfRangeException(nameof(count)); - } - - if (oldValue == null) - { - throw new ArgumentNullException(nameof(oldValue)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); } if (oldValue.Length == 0) @@ -311,8 +326,6 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) throw new ArgumentException("oldValue.Length is 0", nameof(oldValue)); } - newValue = newValue ?? string.Empty; - var readOnlySpan = AsSpan(); int endIndex = startIndex + count; int matchCount = 0; @@ -320,7 +333,7 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) for (int i = startIndex; i < endIndex; i += oldValue.Length) { var span = readOnlySpan.Slice(i, endIndex - i); - var pos = span.IndexOf(oldValue.AsSpan(), StringComparison.Ordinal); + var pos = span.IndexOf(oldValue, StringComparison.Ordinal); if (pos == -1) { break; @@ -340,7 +353,7 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) for (int i = startIndex; i < endIndex; i += oldValue.Length) { var span = readOnlySpan.Slice(i, endIndex - i); - var pos = span.IndexOf(oldValue.AsSpan(), StringComparison.Ordinal); + var pos = span.IndexOf(oldValue, StringComparison.Ordinal); if (pos == -1) { var remain = readOnlySpan.Slice(i); @@ -349,7 +362,7 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) break; } readOnlySpan.Slice(i, pos).CopyTo(newBuffer.AsSpan(newBufferIndex)); - newValue.AsSpan().CopyTo(newBuffer.AsSpan(newBufferIndex + pos)); + newValue.CopyTo(newBuffer.AsSpan(newBufferIndex + pos)); newBufferIndex += pos + newValue.Length; i += pos; } @@ -372,17 +385,17 @@ public void Remove(int startIndex, int length) { if (length < 0) { - throw new ArgumentOutOfRangeException(nameof(length)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(length)); } if (startIndex < 0) { - throw new ArgumentOutOfRangeException(nameof(startIndex)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); } if (length > Length - startIndex) { - throw new ArgumentOutOfRangeException(nameof(length)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(length)); } if (Length == length && startIndex == 0) @@ -396,10 +409,12 @@ public void Remove(int startIndex, int length) return; } - buffer.AsSpan(startIndex + length).CopyTo(buffer.AsSpan(startIndex)); + int remain = startIndex + length; + buffer.AsSpan(remain, Length - remain).CopyTo(buffer.AsSpan(startIndex)); index -= length; } + // Output /// Copy inner buffer to the destination span. diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 57f91ad2..c31bd53b 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -227,6 +227,14 @@ public void AppendLine(T value) AppendLine(); } + static class ExceptionUtil + { + public static void ThrowArgumentOutOfRangeException(string paramName) + { + throw new ArgumentOutOfRangeException(paramName); + } + } + /// /// Replaces all instances of one character with another in this builder. /// @@ -246,12 +254,12 @@ public void Replace(char oldChar, char newChar, int startIndex, int count) int currentLength = Length; if ((uint)startIndex > (uint)currentLength) { - throw new ArgumentOutOfRangeException(nameof(startIndex)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); } if (count < 0 || startIndex > currentLength - count) { - throw new ArgumentOutOfRangeException(nameof(count)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); } int endIndex = startIndex + count; @@ -275,6 +283,8 @@ public void Replace(char oldChar, char newChar, int startIndex, int count) /// are removed from this builder. /// public void Replace(string oldValue, string newValue) => Replace(oldValue, newValue, 0, Length); + + public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue) => Replace(oldValue, newValue, 0, Length); /// /// Replaces all instances of one string with another in part of this builder. @@ -288,22 +298,27 @@ public void Replace(char oldChar, char newChar, int startIndex, int count) /// are removed from this builder. /// public void Replace(string oldValue, string newValue, int startIndex, int count) + { + if (oldValue == null) + { + throw new ArgumentNullException(nameof(oldValue)); + } + + Replace(oldValue.AsSpan(), newValue.AsSpan(), startIndex, count); + } + + public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue, int startIndex, int count) { int currentLength = Length; if ((uint)startIndex > (uint)currentLength) { - throw new ArgumentOutOfRangeException(nameof(startIndex)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); } if (count < 0 || startIndex > currentLength - count) { - throw new ArgumentOutOfRangeException(nameof(count)); - } - - if (oldValue == null) - { - throw new ArgumentNullException(nameof(oldValue)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); } if (oldValue.Length == 0) @@ -311,8 +326,6 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) throw new ArgumentException("oldValue.Length is 0", nameof(oldValue)); } - newValue = newValue ?? string.Empty; - var readOnlySpan = AsSpan(); int endIndex = startIndex + count; int matchCount = 0; @@ -320,7 +333,7 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) for (int i = startIndex; i < endIndex; i += oldValue.Length) { var span = readOnlySpan.Slice(i, endIndex - i); - var pos = span.IndexOf(oldValue.AsSpan(), StringComparison.Ordinal); + var pos = span.IndexOf(oldValue, StringComparison.Ordinal); if (pos == -1) { break; @@ -340,7 +353,7 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) for (int i = startIndex; i < endIndex; i += oldValue.Length) { var span = readOnlySpan.Slice(i, endIndex - i); - var pos = span.IndexOf(oldValue.AsSpan(), StringComparison.Ordinal); + var pos = span.IndexOf(oldValue, StringComparison.Ordinal); if (pos == -1) { var remain = readOnlySpan.Slice(i); @@ -349,7 +362,7 @@ public void Replace(string oldValue, string newValue, int startIndex, int count) break; } readOnlySpan.Slice(i, pos).CopyTo(newBuffer.AsSpan(newBufferIndex)); - newValue.AsSpan().CopyTo(newBuffer.AsSpan(newBufferIndex + pos)); + newValue.CopyTo(newBuffer.AsSpan(newBufferIndex + pos)); newBufferIndex += pos + newValue.Length; i += pos; } @@ -372,17 +385,17 @@ public void Remove(int startIndex, int length) { if (length < 0) { - throw new ArgumentOutOfRangeException(nameof(length)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(length)); } if (startIndex < 0) { - throw new ArgumentOutOfRangeException(nameof(startIndex)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(startIndex)); } if (length > Length - startIndex) { - throw new ArgumentOutOfRangeException(nameof(length)); + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(length)); } if (Length == length && startIndex == 0) @@ -396,10 +409,12 @@ public void Remove(int startIndex, int length) return; } - buffer.AsSpan(startIndex + length).CopyTo(buffer.AsSpan(startIndex)); + int remain = startIndex + length; + buffer.AsSpan(remain, Length - remain).CopyTo(buffer.AsSpan(startIndex)); index -= length; } + // Output /// Copy inner buffer to the destination span. diff --git a/tests/ZString.Tests/ReplaceTest.cs b/tests/ZString.Tests/ReplaceTest.cs index 8c1ead14..25f7f34e 100644 --- a/tests/ZString.Tests/ReplaceTest.cs +++ b/tests/ZString.Tests/ReplaceTest.cs @@ -43,6 +43,19 @@ public void ReplaceStringTest() zsb.ToString().Should().Be(bcl.ToString()); } + using (var zsb = ZString.CreateStringBuilder(notNested: true)) + { + var text = "num num num"; + zsb.Append(text); + var bcl = new StringBuilder(text); + + // over DefaultBufferSize + zsb.Replace("num", new string('1', 32768), 1, text.Length - 2); + bcl.Replace("num", new string('1', 32768), 1, text.Length - 2); + + zsb.ToString().Should().Be(bcl.ToString()); + } + using (var zsb = ZString.CreateStringBuilder()) { var text = "The quick brown dog jumps over the lazy cat."; From 9d586e01fc8d5fb28f2a55276e70bc0e05e8a8b3 Mon Sep 17 00:00:00 2001 From: udaken Date: Mon, 6 Jul 2020 19:28:53 +0900 Subject: [PATCH 062/139] Add Utf16ValueStringBuilder.Insert - Utf16ValueStringBuilder.Insert(int index, string value, int count) - Utf16ValueStringBuilder.Insert(int index, string value) - Utf16ValueStringBuilder.Insert(int index, ReadOnlySpan value, int count) --- .../ZString/Utf16ValueStringBuilder.cs | 53 ++++++++++++++ src/ZString/Utf16ValueStringBuilder.cs | 53 ++++++++++++++ tests/ZString.Tests/InsertTest.cs | 71 +++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 tests/ZString.Tests/InsertTest.cs diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index c31bd53b..dd8ae45f 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -235,6 +235,59 @@ public static void ThrowArgumentOutOfRangeException(string paramName) } } + /// + /// Inserts a string 0 or more times into this builder at the specified position. + /// + /// The index to insert in this builder. + /// The string to insert. + /// The number of times to insert the string. + public void Insert(int index, string value, int count) + { + Insert(index, value.AsSpan(), count); + } + + public void Insert(int index, string value) + { + Insert(index, value.AsSpan(), 1); + } + + public void Insert(int index, ReadOnlySpan value, int count) + { + if (count < 0) + { + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); + } + + int currentLength = Length; + if ((uint)index > (uint)currentLength) + { + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(index)); + } + + if (value.Length == 0 || count == 0) + { + return; + } + + var newSize = index + value.Length * count; + var newBuffer = ArrayPool.Shared.Rent(Math.Max(DefaultBufferSize, newSize)); + + buffer.AsSpan(0, index).CopyTo(newBuffer); + int newBufferIndex = index; + + for (int i = 0; i < count; i++) + { + value.CopyTo(newBuffer.AsSpan(newBufferIndex)); + newBufferIndex += value.Length; + } + + int remainLnegth = this.index - index; + buffer.AsSpan(index, remainLnegth).CopyTo(newBuffer.AsSpan(newBufferIndex)); + + buffer = newBuffer; + this.index = newBufferIndex + remainLnegth; + } + /// /// Replaces all instances of one character with another in this builder. /// diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index c31bd53b..dd8ae45f 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -235,6 +235,59 @@ public static void ThrowArgumentOutOfRangeException(string paramName) } } + /// + /// Inserts a string 0 or more times into this builder at the specified position. + /// + /// The index to insert in this builder. + /// The string to insert. + /// The number of times to insert the string. + public void Insert(int index, string value, int count) + { + Insert(index, value.AsSpan(), count); + } + + public void Insert(int index, string value) + { + Insert(index, value.AsSpan(), 1); + } + + public void Insert(int index, ReadOnlySpan value, int count) + { + if (count < 0) + { + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(count)); + } + + int currentLength = Length; + if ((uint)index > (uint)currentLength) + { + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(index)); + } + + if (value.Length == 0 || count == 0) + { + return; + } + + var newSize = index + value.Length * count; + var newBuffer = ArrayPool.Shared.Rent(Math.Max(DefaultBufferSize, newSize)); + + buffer.AsSpan(0, index).CopyTo(newBuffer); + int newBufferIndex = index; + + for (int i = 0; i < count; i++) + { + value.CopyTo(newBuffer.AsSpan(newBufferIndex)); + newBufferIndex += value.Length; + } + + int remainLnegth = this.index - index; + buffer.AsSpan(index, remainLnegth).CopyTo(newBuffer.AsSpan(newBufferIndex)); + + buffer = newBuffer; + this.index = newBufferIndex + remainLnegth; + } + /// /// Replaces all instances of one character with another in this builder. /// diff --git a/tests/ZString.Tests/InsertTest.cs b/tests/ZString.Tests/InsertTest.cs new file mode 100644 index 00000000..627c7508 --- /dev/null +++ b/tests/ZString.Tests/InsertTest.cs @@ -0,0 +1,71 @@ +using Cysharp.Text; +using FluentAssertions; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public class InsertTest + { + [Fact] + public void InsertStringTest() + { + string initialValue = "--[]--"; + + using (var zsb = ZString.CreateStringBuilder(notNested: true)) + { + string xyz = "xyz"; + + zsb.Append(initialValue); + var bcl = new StringBuilder(initialValue); + + zsb.Insert(3, xyz, 2); + bcl.Insert(3, xyz, 2); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.Insert(3, xyz); + bcl.Insert(3, xyz); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.Insert(0, "<<"); + bcl.Insert(0, "<<"); + zsb.ToString().Should().Be(bcl.ToString()); + + var endIndex = zsb.Length - 1; + zsb.Insert(endIndex, ">>"); + bcl.Insert(endIndex, ">>"); + zsb.ToString().Should().Be(bcl.ToString()); + } + } + + [Fact] + public void InsertLargeStringTest() + { + string initialValue = "--[]--"; + + using (var zsb = ZString.CreateStringBuilder(notNested: true)) + { + string text = new string('X', 32768); + + zsb.Append(initialValue); + var bcl = new StringBuilder(initialValue); + + zsb.Insert(3, text); + bcl.Insert(3, text); + zsb.ToString().Should().Be(bcl.ToString()); + } + } + + [Fact] + public void NotInserted() + { + using (var zsb = ZString.CreateStringBuilder(notNested: true)) + { + var text = "The quick brown dog jumps over the lazy cat."; + zsb.Append(text); + zsb.Insert( 10, ""); + zsb.ToString().Should().Be(text); + } + } + } +} From 8cfd48bce269e96aa7c1f09b0da7e6abf6f7880a Mon Sep 17 00:00:00 2001 From: udaken Date: Wed, 8 Jul 2020 20:09:59 +0900 Subject: [PATCH 063/139] Built-in support for IntPtr/UIntPtr --- .../Utf16ValueStringBuilder.CreateFormatter.cs | 15 ++++++++++++++- .../Utf8ValueStringBuilder.CreateFormatter.cs | 14 ++++++++++++++ .../Utf16ValueStringBuilder.CreateFormatter.cs | 15 ++++++++++++++- .../Utf16ValueStringBuilder.CreateFormatter.tt | 10 +++++++++- .../Utf8ValueStringBuilder.CreateFormatter.cs | 14 ++++++++++++++ .../Utf8ValueStringBuilder.CreateFormatter.tt | 9 +++++++++ tests/ZString.Tests/FormatTest.cs | 13 +++++++++++++ 7 files changed, 87 insertions(+), 3 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 4199c437..71903064 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -66,7 +66,20 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - + if (type == typeof(System.IntPtr)) + { + // ignore format + return new TryFormat((System.IntPtr x, Span dest, out int written, ReadOnlySpan _) => System.IntPtr.Size == 4 + ? x.ToInt32().TryFormat(dest, out written, default) + : x.ToInt64().TryFormat(dest, out written, default)); + } + if (type == typeof(System.UIntPtr)) + { + // ignore format + return new TryFormat((System.UIntPtr x, Span dest, out int written, ReadOnlySpan _) => System.UIntPtr.Size == 4 + ? x.ToUInt32().TryFormat(dest, out written, default) + : x.ToUInt64().TryFormat(dest, out written, default)); + } return null; } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index 7511ae11..c07d40a2 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -68,6 +68,20 @@ static object CreateFormatter(Type type) { return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } + if (type == typeof(System.IntPtr)) + { + // ignore format + return new TryFormat((System.IntPtr x, Span dest, out int written, StandardFormat _) => System.IntPtr.Size == 4 + ? Utf8Formatter.TryFormat(x.ToInt32(), dest, out written, default) + : Utf8Formatter.TryFormat(x.ToInt64(), dest, out written, default)); + } + if (type == typeof(System.UIntPtr)) + { + // ignore format + return new TryFormat((System.UIntPtr x, Span dest, out int written, StandardFormat _) => System.UIntPtr.Size == 4 + ? Utf8Formatter.TryFormat(x.ToUInt32(), dest, out written, default) + : Utf8Formatter.TryFormat(x.ToUInt64(), dest, out written, default)); + } return null; } diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 4199c437..71903064 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -66,7 +66,20 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - + if (type == typeof(System.IntPtr)) + { + // ignore format + return new TryFormat((System.IntPtr x, Span dest, out int written, ReadOnlySpan _) => System.IntPtr.Size == 4 + ? x.ToInt32().TryFormat(dest, out written, default) + : x.ToInt64().TryFormat(dest, out written, default)); + } + if (type == typeof(System.UIntPtr)) + { + // ignore format + return new TryFormat((System.UIntPtr x, Span dest, out int written, ReadOnlySpan _) => System.UIntPtr.Size == 4 + ? x.ToUInt32().TryFormat(dest, out written, default) + : x.ToUInt64().TryFormat(dest, out written, default)); + } return null; } } diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt index 6925ef3c..4acfd5ff 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt @@ -56,7 +56,15 @@ namespace Cysharp.Text return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } <# } #> - +<# foreach(var t in new [] {typeof(IntPtr), typeof(UIntPtr)} ) { var u = t == typeof(UIntPtr); #> + if (type == typeof(<#= t.FullName #>)) + { + // ignore format + return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan _) => <#= t #>.Size == 4 + ? x.To<#= u ? "U" : "" #>Int32().TryFormat(dest, out written, default) + : x.To<#= u ? "U" : "" #>Int64().TryFormat(dest, out written, default)); + } +<# } #> return null; } } diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index 7511ae11..c07d40a2 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -68,6 +68,20 @@ static object CreateFormatter(Type type) { return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } + if (type == typeof(System.IntPtr)) + { + // ignore format + return new TryFormat((System.IntPtr x, Span dest, out int written, StandardFormat _) => System.IntPtr.Size == 4 + ? Utf8Formatter.TryFormat(x.ToInt32(), dest, out written, default) + : Utf8Formatter.TryFormat(x.ToInt64(), dest, out written, default)); + } + if (type == typeof(System.UIntPtr)) + { + // ignore format + return new TryFormat((System.UIntPtr x, Span dest, out int written, StandardFormat _) => System.UIntPtr.Size == 4 + ? Utf8Formatter.TryFormat(x.ToUInt32(), dest, out written, default) + : Utf8Formatter.TryFormat(x.ToUInt64(), dest, out written, default)); + } return null; } diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt index b82d6ef9..6bb13771 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt @@ -41,6 +41,15 @@ namespace Cysharp.Text return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } <# } #> +<# foreach(var t in new [] {typeof(IntPtr), typeof(UIntPtr)} ) { var u = t == typeof(UIntPtr); #> + if (type == typeof(<#= t.FullName #>)) + { + // ignore format + return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, StandardFormat _) => <#= t #>.Size == 4 + ? Utf8Formatter.TryFormat(x.To<#= u ? "U" : "" #>Int32(), dest, out written, default) + : Utf8Formatter.TryFormat(x.To<#= u ? "U" : "" #>Int64(), dest, out written, default)); + } +<# } #> return null; } diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index ae32d52c..bf994bcd 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -97,6 +97,19 @@ public void FormatArgs() ZString.Format("{0:00000000}-{1:00000000}", 100, 200).Should().Be("00000100-00000200"); } + [Fact] + public void FormatIntPtr() + { + // IntPtr/UIntPtr ignores format + Test("abc{0}def{1:X}", new IntPtr(int.MinValue), new IntPtr(int.MaxValue)); + Test("abc{0}def{1:X}", new UIntPtr(uint.MinValue), new UIntPtr(uint.MaxValue)); + if (IntPtr.Size == 8) + { + Test("abc{0}def{1:X}", new IntPtr(long.MinValue), new IntPtr(long.MaxValue)); + Test("abc{0}def{1:X}", new UIntPtr(ulong.MinValue), new UIntPtr(ulong.MaxValue)); + } + } + [Fact] public void Escape() { From 369667c9ff7beb6e9fed4534e06e75b24c4cc7e2 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 11 Jul 2020 12:04:50 +0900 Subject: [PATCH 064/139] Built-in support for Nullable --- ...Utf16ValueStringBuilder.CreateFormatter.cs | 60 +++++++++++++++++++ .../ZString/Utf16ValueStringBuilder.cs | 21 +++++++ .../Utf8ValueStringBuilder.CreateFormatter.cs | 60 +++++++++++++++++++ .../Scripts/ZString/Utf8ValueStringBuilder.cs | 21 +++++++ ...Utf16ValueStringBuilder.CreateFormatter.cs | 60 +++++++++++++++++++ ...Utf16ValueStringBuilder.CreateFormatter.tt | 6 ++ src/ZString/Utf16ValueStringBuilder.cs | 21 +++++++ .../Utf8ValueStringBuilder.CreateFormatter.cs | 60 +++++++++++++++++++ .../Utf8ValueStringBuilder.CreateFormatter.tt | 6 ++ src/ZString/Utf8ValueStringBuilder.cs | 21 +++++++ tests/ZString.Tests/FormatTest.cs | 9 +++ 11 files changed, 345 insertions(+) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 71903064..b02bca8e 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -66,6 +66,66 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } + if (type == typeof(System.SByte?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int16?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int32?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int64?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Byte?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt16?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt32?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt64?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Single?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Double?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.TimeSpan?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.DateTime?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.DateTimeOffset?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Decimal?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Guid?)) + { + return CreateNullableFormatter(); + } if (type == typeof(System.IntPtr)) { // ignore format diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index b589b3d4..68f7bc73 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -278,6 +278,27 @@ public static void RegisterTryFormat(TryFormat formatMethod) FormatterCache.TryFormatDelegate = formatMethod; } + static TryFormat CreateNullableFormatter() where T : struct + { + return new TryFormat((T? x, Span dest, out int written, ReadOnlySpan format) => + { + if (x == null) + { + written = 0; + return true; + } + return FormatterCache.TryFormatDelegate(x.Value, dest, out written, format); + }); + } + + /// + /// Supports the Nullable type for a given struct type. + /// + public static void EnableNullableFormat() where T : struct + { + RegisterTryFormat(CreateNullableFormatter()); + } + public static class FormatterCache { public static TryFormat TryFormatDelegate; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index c07d40a2..3a5f0295 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -68,6 +68,66 @@ static object CreateFormatter(Type type) { return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } + if (type == typeof(System.Byte?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.DateTime?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.DateTimeOffset?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Decimal?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Double?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Guid?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int16?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int32?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int64?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.SByte?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Single?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.TimeSpan?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt16?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt32?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt64?)) + { + return CreateNullableFormatter(); + } if (type == typeof(System.IntPtr)) { // ignore format diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index eef8142a..764de4f0 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -294,6 +294,27 @@ public static void RegisterTryFormat(TryFormat formatMethod) FormatterCache.TryFormatDelegate = formatMethod; } + static TryFormat CreateNullableFormatter() where T : struct + { + return new TryFormat((T? x, Span destination, out int written, StandardFormat format) => + { + if (x == null) + { + written = 0; + return true; + } + return FormatterCache.TryFormatDelegate(x.Value, destination, out written, format); + }); + } + + /// + /// Supports the Nullable type for a given struct type. + /// + public static void EnableNullableFormat() where T : struct + { + RegisterTryFormat(CreateNullableFormatter()); + } + public static class FormatterCache { public static TryFormat TryFormatDelegate; diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 71903064..b02bca8e 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -66,6 +66,66 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } + if (type == typeof(System.SByte?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int16?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int32?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int64?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Byte?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt16?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt32?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt64?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Single?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Double?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.TimeSpan?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.DateTime?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.DateTimeOffset?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Decimal?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Guid?)) + { + return CreateNullableFormatter(); + } if (type == typeof(System.IntPtr)) { // ignore format diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt index 4acfd5ff..829856fc 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt @@ -56,6 +56,12 @@ namespace Cysharp.Text return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } <# } #> +<# foreach(var t in spanFormattablesA.Concat(spanFormattablesB).Concat(spanFormattablesC)) { #> + if (type == typeof(<#= t.FullName #>?)) + { + return CreateNullableFormatter<<#= t.FullName #>>(); + } +<# } #> <# foreach(var t in new [] {typeof(IntPtr), typeof(UIntPtr)} ) { var u = t == typeof(UIntPtr); #> if (type == typeof(<#= t.FullName #>)) { diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index b589b3d4..68f7bc73 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -278,6 +278,27 @@ public static void RegisterTryFormat(TryFormat formatMethod) FormatterCache.TryFormatDelegate = formatMethod; } + static TryFormat CreateNullableFormatter() where T : struct + { + return new TryFormat((T? x, Span dest, out int written, ReadOnlySpan format) => + { + if (x == null) + { + written = 0; + return true; + } + return FormatterCache.TryFormatDelegate(x.Value, dest, out written, format); + }); + } + + /// + /// Supports the Nullable type for a given struct type. + /// + public static void EnableNullableFormat() where T : struct + { + RegisterTryFormat(CreateNullableFormatter()); + } + public static class FormatterCache { public static TryFormat TryFormatDelegate; diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index c07d40a2..3a5f0295 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -68,6 +68,66 @@ static object CreateFormatter(Type type) { return new TryFormat((System.UInt64 x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } + if (type == typeof(System.Byte?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.DateTime?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.DateTimeOffset?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Decimal?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Double?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Guid?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int16?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int32?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Int64?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.SByte?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.Single?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.TimeSpan?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt16?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt32?)) + { + return CreateNullableFormatter(); + } + if (type == typeof(System.UInt64?)) + { + return CreateNullableFormatter(); + } if (type == typeof(System.IntPtr)) { // ignore format diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt index 6bb13771..0ba5677a 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt @@ -41,6 +41,12 @@ namespace Cysharp.Text return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } <# } #> +<# foreach(var t in spanFormattables) { #> + if (type == typeof(<#= t.FullName #>?)) + { + return CreateNullableFormatter<<#= t.FullName #>>(); + } +<# } #> <# foreach(var t in new [] {typeof(IntPtr), typeof(UIntPtr)} ) { var u = t == typeof(UIntPtr); #> if (type == typeof(<#= t.FullName #>)) { diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index eef8142a..764de4f0 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -294,6 +294,27 @@ public static void RegisterTryFormat(TryFormat formatMethod) FormatterCache.TryFormatDelegate = formatMethod; } + static TryFormat CreateNullableFormatter() where T : struct + { + return new TryFormat((T? x, Span destination, out int written, StandardFormat format) => + { + if (x == null) + { + written = 0; + return true; + } + return FormatterCache.TryFormatDelegate(x.Value, destination, out written, format); + }); + } + + /// + /// Supports the Nullable type for a given struct type. + /// + public static void EnableNullableFormat() where T : struct + { + RegisterTryFormat(CreateNullableFormatter()); + } + public static class FormatterCache { public static TryFormat TryFormatDelegate; diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index bf994bcd..deb8ce63 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -85,6 +85,15 @@ public void DoubleFormat3() Test("abc{0}def{1}ghi", 100, 200); } + [Fact] + public void Nullable() + { + Test("abc{0}def{1}ghi", (int?)100, (int?)1); + Test("abc{0:X}def{1:X}ghi", (int?)100, (int?)1); + Test("abc{0}def{1}ghi", (Guid?)Guid.NewGuid(), (Guid?)null); + Test("abc{0:e}def{1:e}ghi", (double?)Math.PI, (double?)null); + } + [Fact] public void Comment() { From 4d8a383ae51de19fec1954876517719d9f6a5838 Mon Sep 17 00:00:00 2001 From: udaken Date: Wed, 15 Jul 2020 23:02:30 +0900 Subject: [PATCH 065/139] update Utf8ValueStringBuilder.Append(char value, int repeatCount) --- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 26 +++++++----- src/ZString/Utf8ValueStringBuilder.cs | 26 +++++++----- tests/ZString.Tests/Utf8StringBuilderTest.cs | 40 +++++++++++++++++++ 3 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 tests/ZString.Tests/Utf8StringBuilderTest.cs diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index a80f39e5..b5c9c10d 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -168,18 +168,26 @@ public void Append(char value, int repeatCount) throw new ArgumentOutOfRangeException(nameof(repeatCount)); } - var maxLen = UTF8NoBom.GetMaxByteCount(1); - Span utf8Bytes = stackalloc byte[maxLen]; - ReadOnlySpan chars = stackalloc char[1] { value }; + if (value <= 0x7F) // ASCII + { + GetSpan(repeatCount).Fill((byte)value); + Advance(repeatCount); + } + else + { + var maxLen = UTF8NoBom.GetMaxByteCount(1); + Span utf8Bytes = stackalloc byte[maxLen]; + ReadOnlySpan chars = stackalloc char[1] { value }; - int len = UTF8NoBom.GetBytes(chars, utf8Bytes); + int len = UTF8NoBom.GetBytes(chars, utf8Bytes); - TryGrow(len * repeatCount); + TryGrow(len * repeatCount); - for (int i = 0; i < repeatCount; i++) - { - utf8Bytes.CopyTo(GetSpan(len)); - Advance(len); + for (int i = 0; i < repeatCount; i++) + { + utf8Bytes.CopyTo(GetSpan(len)); + Advance(len); + } } } diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index a80f39e5..b5c9c10d 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -168,18 +168,26 @@ public void Append(char value, int repeatCount) throw new ArgumentOutOfRangeException(nameof(repeatCount)); } - var maxLen = UTF8NoBom.GetMaxByteCount(1); - Span utf8Bytes = stackalloc byte[maxLen]; - ReadOnlySpan chars = stackalloc char[1] { value }; + if (value <= 0x7F) // ASCII + { + GetSpan(repeatCount).Fill((byte)value); + Advance(repeatCount); + } + else + { + var maxLen = UTF8NoBom.GetMaxByteCount(1); + Span utf8Bytes = stackalloc byte[maxLen]; + ReadOnlySpan chars = stackalloc char[1] { value }; - int len = UTF8NoBom.GetBytes(chars, utf8Bytes); + int len = UTF8NoBom.GetBytes(chars, utf8Bytes); - TryGrow(len * repeatCount); + TryGrow(len * repeatCount); - for (int i = 0; i < repeatCount; i++) - { - utf8Bytes.CopyTo(GetSpan(len)); - Advance(len); + for (int i = 0; i < repeatCount; i++) + { + utf8Bytes.CopyTo(GetSpan(len)); + Advance(len); + } } } diff --git a/tests/ZString.Tests/Utf8StringBuilderTest.cs b/tests/ZString.Tests/Utf8StringBuilderTest.cs new file mode 100644 index 00000000..47ffdda2 --- /dev/null +++ b/tests/ZString.Tests/Utf8StringBuilderTest.cs @@ -0,0 +1,40 @@ +using Cysharp.Text; +using FluentAssertions; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public class Utf8StringBuilderTest + { + + [Fact] + public void AppendCharRepeat() + { + using (var zsb = ZString.CreateUtf8StringBuilder(notNested: true)) + { + var text = "foo"; + zsb.Append(text); + var bcl = new StringBuilder(text); + + // ASCII + zsb.Append('\x7F', 10); + bcl.Append('\x7F', 10); + zsb.ToString().Should().Be(bcl.ToString()); + + // Non-ASCII + zsb.Append('\x80', 10); + bcl.Append('\x80', 10); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.Append('\u9bd6', 10); + bcl.Append('\u9bd6', 10); + zsb.ToString().Should().Be(bcl.ToString()); + } + + } + } +} From f14f536f68e95832bd823f35c42dbcd454ec648c Mon Sep 17 00:00:00 2001 From: udaken Date: Tue, 14 Jul 2020 21:42:54 +0900 Subject: [PATCH 066/139] Fallback if IFormattable is supported --- .../Assets/Scripts/ZString/Utf16ValueStringBuilder.cs | 4 +++- .../Assets/Scripts/ZString/Utf8ValueStringBuilder.cs | 4 +++- src/ZString/Utf16ValueStringBuilder.cs | 4 +++- src/ZString/Utf8ValueStringBuilder.cs | 4 +++- tests/ZString.Tests/FormatTest.cs | 9 +++++++++ 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 68f7bc73..db853cf9 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -347,7 +347,9 @@ static bool TryFormatDefault(T value, Span dest, out int written, ReadOnly return true; } - var s = value.ToString(); + var s = (value is IFormattable formattable && format.Length != 0) ? + formattable.ToString(format.ToString(), null) : + value.ToString(); // also use this length when result is false. written = s.Length; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 764de4f0..e070771f 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -344,7 +344,9 @@ static bool TryFormatDefault(T value, Span dest, out int written, Standard return true; } - var s = value.ToString(); + var s = typeof(T) == typeof(string) ? Unsafe.As(value) : + (value is IFormattable formattable && format != default) ? formattable.ToString(format.ToString(), null) : + value.ToString(); // also use this length when result is false. written = UTF8NoBom.GetMaxByteCount(s.Length); diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 68f7bc73..db853cf9 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -347,7 +347,9 @@ static bool TryFormatDefault(T value, Span dest, out int written, ReadOnly return true; } - var s = value.ToString(); + var s = (value is IFormattable formattable && format.Length != 0) ? + formattable.ToString(format.ToString(), null) : + value.ToString(); // also use this length when result is false. written = s.Length; diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 764de4f0..e070771f 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -344,7 +344,9 @@ static bool TryFormatDefault(T value, Span dest, out int written, Standard return true; } - var s = value.ToString(); + var s = typeof(T) == typeof(string) ? Unsafe.As(value) : + (value is IFormattable formattable && format != default) ? formattable.ToString(format.ToString(), null) : + value.ToString(); // also use this length when result is false. written = UTF8NoBom.GetMaxByteCount(s.Length); diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index deb8ce63..74c3d1db 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -2,6 +2,7 @@ using FluentAssertions; using System; using System.Buffers; +using System.Numerics; using System.Text; using Xunit; @@ -119,6 +120,14 @@ public void FormatIntPtr() } } + [Fact] + public void FormattableObject() + { + Test("abc{0:}def{1:F3}", (object)default(Vector2), (object)new Vector2(MathF.PI)); + Test("abc{0:E0}def{1:N}", (object)new Vector3(float.MinValue, float.NaN, float.MaxValue), + (object)new Vector3(MathF.PI)); + } + [Fact] public void Escape() { From 2c0598299816461c7726cfe4570218b7b42b725b Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 4 Jul 2020 15:49:26 +0900 Subject: [PATCH 067/139] Optimize ZString.Join(IReadOnlyList) --- .../Assets/Scripts/ZString/ZString.cs | 43 +++++++++++++++---- src/ZString/ZString.cs | 43 +++++++++++++++---- 2 files changed, 70 insertions(+), 16 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 560c92e5..fc67c0b4 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; @@ -44,7 +45,8 @@ public static string Join(char separator, params T[] values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, List values) { - return Join(separator, (IList)values); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, (IReadOnlyList)values); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -63,7 +65,8 @@ public static string Join(char separator, IEnumerable values) public static string Join(char separator, ICollection values) { - return Join(separator, values.AsEnumerable()); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, values.AsEnumerable()); } public static string Join(char separator, IList values) @@ -74,12 +77,14 @@ public static string Join(char separator, IList values) public static string Join(char separator, IReadOnlyList values) { - return Join(separator, values.AsEnumerable()); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, values); } public static string Join(char separator, IReadOnlyCollection values) { - return Join(separator, values.AsEnumerable()); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, values.AsEnumerable()); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -91,7 +96,7 @@ public static string Join(string separator, params T[] values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, List values) { - return JoinInternal(separator.AsSpan(), values); + return JoinInternal(separator.AsSpan(), (IReadOnlyList)values); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -112,7 +117,7 @@ public static string Join(string separator, IList values) public static string Join(string separator, IReadOnlyList values) { - return JoinInternal(separator.AsSpan(), values.AsEnumerable()); + return JoinInternal(separator.AsSpan(), values); } public static string Join(string separator, IReadOnlyCollection values) @@ -135,7 +140,7 @@ public static string Concat(params T[] values) /// Concatenates the string representation of some specified objects. public static string Concat(List values) { - return JoinInternal(default, values); + return JoinInternal(default, (IReadOnlyList)values); } /// Concatenates the string representation of some specified objects. @@ -159,7 +164,7 @@ public static string Concat(IList values) /// Concatenates the string representation of some specified objects. public static string Concat(IReadOnlyList values) { - return JoinInternal(default, values.AsEnumerable()); + return JoinInternal(default, values); } /// Concatenates the string representation of some specified objects. @@ -174,7 +179,29 @@ public static string Concat(IEnumerable values) return JoinInternal(default, values); } + readonly struct ReadOnlyListAdoptor : IReadOnlyList + { + readonly IList _list; + + public ReadOnlyListAdoptor(IList list) => _list = list; + + public T this[int index] => _list[index]; + + public int Count => _list.Count; + + public IEnumerator GetEnumerator() => _list.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + static string JoinInternal(ReadOnlySpan separator, IList values) + { + var readOnlyList = values as IReadOnlyList; + readOnlyList = readOnlyList ?? new ReadOnlyListAdoptor(values); // occur boxing + return JoinInternal(separator, readOnlyList); + } + + static string JoinInternal(ReadOnlySpan separator, IReadOnlyList values) { var count = values.Count; if (count == 0) diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 560c92e5..fc67c0b4 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; @@ -44,7 +45,8 @@ public static string Join(char separator, params T[] values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(char separator, List values) { - return Join(separator, (IList)values); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, (IReadOnlyList)values); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -63,7 +65,8 @@ public static string Join(char separator, IEnumerable values) public static string Join(char separator, ICollection values) { - return Join(separator, values.AsEnumerable()); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, values.AsEnumerable()); } public static string Join(char separator, IList values) @@ -74,12 +77,14 @@ public static string Join(char separator, IList values) public static string Join(char separator, IReadOnlyList values) { - return Join(separator, values.AsEnumerable()); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, values); } public static string Join(char separator, IReadOnlyCollection values) { - return Join(separator, values.AsEnumerable()); + ReadOnlySpan s = stackalloc char[1] { separator }; + return JoinInternal(s, values.AsEnumerable()); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -91,7 +96,7 @@ public static string Join(string separator, params T[] values) /// Concatenates the elements of an array, using the specified seperator between each element. public static string Join(string separator, List values) { - return JoinInternal(separator.AsSpan(), values); + return JoinInternal(separator.AsSpan(), (IReadOnlyList)values); } /// Concatenates the elements of an array, using the specified seperator between each element. @@ -112,7 +117,7 @@ public static string Join(string separator, IList values) public static string Join(string separator, IReadOnlyList values) { - return JoinInternal(separator.AsSpan(), values.AsEnumerable()); + return JoinInternal(separator.AsSpan(), values); } public static string Join(string separator, IReadOnlyCollection values) @@ -135,7 +140,7 @@ public static string Concat(params T[] values) /// Concatenates the string representation of some specified objects. public static string Concat(List values) { - return JoinInternal(default, values); + return JoinInternal(default, (IReadOnlyList)values); } /// Concatenates the string representation of some specified objects. @@ -159,7 +164,7 @@ public static string Concat(IList values) /// Concatenates the string representation of some specified objects. public static string Concat(IReadOnlyList values) { - return JoinInternal(default, values.AsEnumerable()); + return JoinInternal(default, values); } /// Concatenates the string representation of some specified objects. @@ -174,7 +179,29 @@ public static string Concat(IEnumerable values) return JoinInternal(default, values); } + readonly struct ReadOnlyListAdoptor : IReadOnlyList + { + readonly IList _list; + + public ReadOnlyListAdoptor(IList list) => _list = list; + + public T this[int index] => _list[index]; + + public int Count => _list.Count; + + public IEnumerator GetEnumerator() => _list.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + static string JoinInternal(ReadOnlySpan separator, IList values) + { + var readOnlyList = values as IReadOnlyList; + readOnlyList = readOnlyList ?? new ReadOnlyListAdoptor(values); // occur boxing + return JoinInternal(separator, readOnlyList); + } + + static string JoinInternal(ReadOnlySpan separator, IReadOnlyList values) { var count = values.Count; if (count == 0) From 351d4a7d0e07d083fd8ba4377f4ae79ab479c94b Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 4 Jul 2020 17:46:57 +0900 Subject: [PATCH 068/139] Add StringBuilder.AppendJoin --- .../Benchmarks/StringBuilderAppendJoin.cs | 59 +++ .../Scripts/ZString/ReadOnlyListAdaptor.cs | 25 ++ .../ZString/StringBuilder.AppendJoin.cs | 414 ++++++++++++++++++ .../Assets/Scripts/ZString/ZString.cs | 89 +--- src/ZString/ReadOnlyListAdaptor.cs | 25 ++ src/ZString/StringBuilder.AppendJoin.cs | 414 ++++++++++++++++++ src/ZString/StringBuilder.AppendJoin.tt | 224 ++++++++++ src/ZString/ZString.cs | 89 +--- src/ZString/ZString.csproj | 9 + tests/ZString.Tests/AppendJoinTest.cs | 213 +++++++++ 10 files changed, 1393 insertions(+), 168 deletions(-) create mode 100644 sandbox/PerfBenchmark/Benchmarks/StringBuilderAppendJoin.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ReadOnlyListAdaptor.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/StringBuilder.AppendJoin.cs create mode 100644 src/ZString/ReadOnlyListAdaptor.cs create mode 100644 src/ZString/StringBuilder.AppendJoin.cs create mode 100644 src/ZString/StringBuilder.AppendJoin.tt create mode 100644 tests/ZString.Tests/AppendJoinTest.cs diff --git a/sandbox/PerfBenchmark/Benchmarks/StringBuilderAppendJoin.cs b/sandbox/PerfBenchmark/Benchmarks/StringBuilderAppendJoin.cs new file mode 100644 index 00000000..ce701a68 --- /dev/null +++ b/sandbox/PerfBenchmark/Benchmarks/StringBuilderAppendJoin.cs @@ -0,0 +1,59 @@ +using BenchmarkDotNet.Attributes; +using Cysharp.Text; +using System; +using System.Text; + +namespace PerfBenchmark.Benchmarks +{ + [Config(typeof(BenchmarkConfig))] + public class StringBuilderAppendJoin + { + double[] dValues; + float[] fValues; + decimal[] mValues; + public StringBuilderAppendJoin() + { + dValues = new[] { 0d, double.MaxValue, double.MinValue }; + fValues = new[] { 0f, float.MaxValue, float.MinValue }; + mValues = new[] { 0m, decimal.MaxValue, decimal.MinValue }; + + if (StringBuilder() != ZStringBuilder()) + throw new Exception(); + } + + +#if NETCOREAPP || NETSTANDARD2_1 + [Benchmark(Baseline = true)] + public int StringBuilder() + { + var sb = new StringBuilder(); + sb.Append("double: "); + sb.AppendJoin(", ", dValues); + sb.AppendLine(); + sb.Append("float: "); + sb.AppendJoin(", ", fValues); + sb.AppendLine(); + sb.Append("decimal: "); + sb.AppendJoin(", ", mValues); + sb.AppendLine(); + return sb.Length; + } +#endif + + [Benchmark] + public int ZStringBuilder() + { + using var sb = ZString.CreateStringBuilder(); + sb.Append("double: "); + sb.AppendJoin(", ", dValues); + sb.AppendLine(); + sb.Append("float: "); + sb.AppendJoin(", ", fValues); + sb.AppendLine(); + sb.Append("decimal: "); + sb.AppendJoin(", ", mValues); + sb.AppendLine(); + return sb.Length; + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ReadOnlyListAdaptor.cs b/src/ZString.Unity/Assets/Scripts/ZString/ReadOnlyListAdaptor.cs new file mode 100644 index 00000000..bc8dbd55 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ReadOnlyListAdaptor.cs @@ -0,0 +1,25 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Cysharp.Text +{ + /// + /// Most IList interface-implementing classes implement the IReadOnlyList interface. + /// This is for the rare class that does not implement the IList interface. + /// + /// + internal readonly struct ReadOnlyListAdaptor : IReadOnlyList + { + readonly IList _list; + + public ReadOnlyListAdaptor(IList list) => _list = list; + + public T this[int index] => _list[index]; + + public int Count => _list.Count; + + public IEnumerator GetEnumerator() => _list.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/StringBuilder.AppendJoin.cs b/src/ZString.Unity/Assets/Scripts/ZString/StringBuilder.AppendJoin.cs new file mode 100644 index 00000000..19f5e3e1 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/StringBuilder.AppendJoin.cs @@ -0,0 +1,414 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(char separator, params T[] values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsSpan()); + } + + public void AppendJoin(char separator, List values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, (IReadOnlyList)values); + } + + public void AppendJoin(char separator, ReadOnlySpan values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified char separator between each member. + /// + /// + /// + /// + public void AppendJoin(char separator, IEnumerable values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, ICollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + public void AppendJoin(char separator, IList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyCollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(string separator, params T[] values) + { + AppendJoinInternal(separator.AsSpan(), values.AsSpan()); + } + + public void AppendJoin(string separator, List values) + { + AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); + } + + public void AppendJoin(string separator, ReadOnlySpan values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified separator between each member. + /// + /// + /// + /// + public void AppendJoin(string separator, IEnumerable values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, ICollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public void AppendJoin(string separator, IList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyCollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IList values) + { + var readOnlyList = values as IReadOnlyList; + // Boxing will occur, but JIT will be de-virtualized. + readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); + AppendJoinInternal(separator, readOnlyList); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) + { + var isFirst = true; + foreach (var item in values) + { + if (!isFirst) + { + Append(separator); + } + else + { + isFirst = false; + } + + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + } + public partial struct Utf8ValueStringBuilder + { + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(char separator, params T[] values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsSpan()); + } + + public void AppendJoin(char separator, List values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, (IReadOnlyList)values); + } + + public void AppendJoin(char separator, ReadOnlySpan values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified char separator between each member. + /// + /// + /// + /// + public void AppendJoin(char separator, IEnumerable values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, ICollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + public void AppendJoin(char separator, IList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyCollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(string separator, params T[] values) + { + AppendJoinInternal(separator.AsSpan(), values.AsSpan()); + } + + public void AppendJoin(string separator, List values) + { + AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); + } + + public void AppendJoin(string separator, ReadOnlySpan values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified separator between each member. + /// + /// + /// + /// + public void AppendJoin(string separator, IEnumerable values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, ICollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public void AppendJoin(string separator, IList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyCollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IList values) + { + var readOnlyList = values as IReadOnlyList; + // Boxing will occur, but JIT will be de-virtualized. + readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); + AppendJoinInternal(separator, readOnlyList); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) + { + var isFirst = true; + foreach (var item in values) + { + if (!isFirst) + { + Append(separator); + } + else + { + isFirst = false; + } + + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index fc67c0b4..8f82ab1b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -179,25 +179,11 @@ public static string Concat(IEnumerable values) return JoinInternal(default, values); } - readonly struct ReadOnlyListAdoptor : IReadOnlyList - { - readonly IList _list; - - public ReadOnlyListAdoptor(IList list) => _list = list; - - public T this[int index] => _list[index]; - - public int Count => _list.Count; - - public IEnumerator GetEnumerator() => _list.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } - static string JoinInternal(ReadOnlySpan separator, IList values) { var readOnlyList = values as IReadOnlyList; - readOnlyList = readOnlyList ?? new ReadOnlyListAdoptor(values); // occur boxing + // Boxing will occur, but JIT will be de-virtualized. + readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); return JoinInternal(separator, readOnlyList); } @@ -216,27 +202,7 @@ static string JoinInternal(ReadOnlySpan separator, IReadOnlyList val var sb = new Utf16ValueStringBuilder(true); try { - for (int i = 0; i < count; i++) - { - if (i != 0) - { - sb.Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } + sb.AppendJoinInternal(separator, values); return sb.ToString(); } finally @@ -259,27 +225,7 @@ static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan valu var sb = new Utf16ValueStringBuilder(true); try { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } + sb.AppendJoinInternal(separator, values); return sb.ToString(); } finally @@ -293,32 +239,7 @@ static string JoinInternal(ReadOnlySpan separator, IEnumerable value var sb = new Utf16ValueStringBuilder(true); try { - var isFirst = true; - foreach (var item in values) - { - if (!isFirst) - { - sb.Append(separator); - } - else - { - isFirst = false; - } - - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } - + sb.AppendJoinInternal(separator, values); return sb.ToString(); } finally diff --git a/src/ZString/ReadOnlyListAdaptor.cs b/src/ZString/ReadOnlyListAdaptor.cs new file mode 100644 index 00000000..bc8dbd55 --- /dev/null +++ b/src/ZString/ReadOnlyListAdaptor.cs @@ -0,0 +1,25 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Cysharp.Text +{ + /// + /// Most IList interface-implementing classes implement the IReadOnlyList interface. + /// This is for the rare class that does not implement the IList interface. + /// + /// + internal readonly struct ReadOnlyListAdaptor : IReadOnlyList + { + readonly IList _list; + + public ReadOnlyListAdaptor(IList list) => _list = list; + + public T this[int index] => _list[index]; + + public int Count => _list.Count; + + public IEnumerator GetEnumerator() => _list.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } +} diff --git a/src/ZString/StringBuilder.AppendJoin.cs b/src/ZString/StringBuilder.AppendJoin.cs new file mode 100644 index 00000000..19f5e3e1 --- /dev/null +++ b/src/ZString/StringBuilder.AppendJoin.cs @@ -0,0 +1,414 @@ +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + public partial struct Utf16ValueStringBuilder + { + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(char separator, params T[] values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsSpan()); + } + + public void AppendJoin(char separator, List values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, (IReadOnlyList)values); + } + + public void AppendJoin(char separator, ReadOnlySpan values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified char separator between each member. + /// + /// + /// + /// + public void AppendJoin(char separator, IEnumerable values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, ICollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + public void AppendJoin(char separator, IList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyCollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(string separator, params T[] values) + { + AppendJoinInternal(separator.AsSpan(), values.AsSpan()); + } + + public void AppendJoin(string separator, List values) + { + AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); + } + + public void AppendJoin(string separator, ReadOnlySpan values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified separator between each member. + /// + /// + /// + /// + public void AppendJoin(string separator, IEnumerable values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, ICollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public void AppendJoin(string separator, IList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyCollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IList values) + { + var readOnlyList = values as IReadOnlyList; + // Boxing will occur, but JIT will be de-virtualized. + readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); + AppendJoinInternal(separator, readOnlyList); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) + { + var isFirst = true; + foreach (var item in values) + { + if (!isFirst) + { + Append(separator); + } + else + { + isFirst = false; + } + + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + } + public partial struct Utf8ValueStringBuilder + { + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(char separator, params T[] values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsSpan()); + } + + public void AppendJoin(char separator, List values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, (IReadOnlyList)values); + } + + public void AppendJoin(char separator, ReadOnlySpan values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified char separator between each member. + /// + /// + /// + /// + public void AppendJoin(char separator, IEnumerable values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, ICollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + public void AppendJoin(char separator, IList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyCollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(string separator, params T[] values) + { + AppendJoinInternal(separator.AsSpan(), values.AsSpan()); + } + + public void AppendJoin(string separator, List values) + { + AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); + } + + public void AppendJoin(string separator, ReadOnlySpan values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified separator between each member. + /// + /// + /// + /// + public void AppendJoin(string separator, IEnumerable values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, ICollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public void AppendJoin(string separator, IList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyCollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IList values) + { + var readOnlyList = values as IReadOnlyList; + // Boxing will occur, but JIT will be de-virtualized. + readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); + AppendJoinInternal(separator, readOnlyList); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) + { + var isFirst = true; + foreach (var item in values) + { + if (!isFirst) + { + Append(separator); + } + else + { + isFirst = false; + } + + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + } +} diff --git a/src/ZString/StringBuilder.AppendJoin.tt b/src/ZString/StringBuilder.AppendJoin.tt new file mode 100644 index 00000000..937dab5d --- /dev/null +++ b/src/ZString/StringBuilder.AppendJoin.tt @@ -0,0 +1,224 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + + string[] utfTypes = new [] { "Utf16", "Utf8" }; +#> +using System; +using System.Text; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ +<# foreach(var utf in utfTypes) { #> + public partial struct <#= utf #>ValueStringBuilder + { + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(char separator, params T[] values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsSpan()); + } + + public void AppendJoin(char separator, List values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, (IReadOnlyList)values); + } + + public void AppendJoin(char separator, ReadOnlySpan values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified char separator between each member. + /// + /// + /// + /// + public void AppendJoin(char separator, IEnumerable values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, ICollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + public void AppendJoin(char separator, IList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyList values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values); + } + + public void AppendJoin(char separator, IReadOnlyCollection values) + { + ReadOnlySpan s = stackalloc char[1] { separator }; + AppendJoinInternal(s, values.AsEnumerable()); + } + + /// + /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. + /// + /// + /// + /// + public void AppendJoin(string separator, params T[] values) + { + AppendJoinInternal(separator.AsSpan(), values.AsSpan()); + } + + public void AppendJoin(string separator, List values) + { + AppendJoinInternal(separator.AsSpan(), (IReadOnlyList)values); + } + + public void AppendJoin(string separator, ReadOnlySpan values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + /// + /// Concatenates and appends the members of a collection, using the specified separator between each member. + /// + /// + /// + /// + public void AppendJoin(string separator, IEnumerable values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, ICollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + public void AppendJoin(string separator, IList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyList values) + { + AppendJoinInternal(separator.AsSpan(), values); + } + + public void AppendJoin(string separator, IReadOnlyCollection values) + { + AppendJoinInternal(separator.AsSpan(), values.AsEnumerable()); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IList values) + { + var readOnlyList = values as IReadOnlyList; + // Boxing will occur, but JIT will be de-virtualized. + readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); + AppendJoinInternal(separator, readOnlyList); + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IReadOnlyList values) + { + var count = values.Count; + for (int i = 0; i < count; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, ReadOnlySpan values) + { + for (int i = 0; i < values.Length; i++) + { + if (i != 0) + { + Append(separator); + } + + var item = values[i]; + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + + internal void AppendJoinInternal(ReadOnlySpan separator, IEnumerable values) + { + var isFirst = true; + foreach (var item in values) + { + if (!isFirst) + { + Append(separator); + } + else + { + isFirst = false; + } + + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(item); + if (!string.IsNullOrEmpty(s)) + { + Append(s); + } + } + else + { + Append(item); + } + } + } + } +<# } // foreach(utf) #> +} diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index fc67c0b4..8f82ab1b 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -179,25 +179,11 @@ public static string Concat(IEnumerable values) return JoinInternal(default, values); } - readonly struct ReadOnlyListAdoptor : IReadOnlyList - { - readonly IList _list; - - public ReadOnlyListAdoptor(IList list) => _list = list; - - public T this[int index] => _list[index]; - - public int Count => _list.Count; - - public IEnumerator GetEnumerator() => _list.GetEnumerator(); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } - static string JoinInternal(ReadOnlySpan separator, IList values) { var readOnlyList = values as IReadOnlyList; - readOnlyList = readOnlyList ?? new ReadOnlyListAdoptor(values); // occur boxing + // Boxing will occur, but JIT will be de-virtualized. + readOnlyList = readOnlyList ?? new ReadOnlyListAdaptor(values); return JoinInternal(separator, readOnlyList); } @@ -216,27 +202,7 @@ static string JoinInternal(ReadOnlySpan separator, IReadOnlyList val var sb = new Utf16ValueStringBuilder(true); try { - for (int i = 0; i < count; i++) - { - if (i != 0) - { - sb.Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } + sb.AppendJoinInternal(separator, values); return sb.ToString(); } finally @@ -259,27 +225,7 @@ static string JoinInternal(ReadOnlySpan separator, ReadOnlySpan valu var sb = new Utf16ValueStringBuilder(true); try { - for (int i = 0; i < values.Length; i++) - { - if (i != 0) - { - sb.Append(separator); - } - - var item = values[i]; - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } + sb.AppendJoinInternal(separator, values); return sb.ToString(); } finally @@ -293,32 +239,7 @@ static string JoinInternal(ReadOnlySpan separator, IEnumerable value var sb = new Utf16ValueStringBuilder(true); try { - var isFirst = true; - foreach (var item in values) - { - if (!isFirst) - { - sb.Append(separator); - } - else - { - isFirst = false; - } - - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(item); - if (!string.IsNullOrEmpty(s)) - { - sb.Append(s); - } - } - else - { - sb.Append(item); - } - } - + sb.AppendJoinInternal(separator, values); return sb.ToString(); } finally diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index a9ce33aa..eab6ce58 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -35,6 +35,10 @@ TextTemplatingFileGenerator PreparedFormat.cs + + TextTemplatingFileGenerator + StringBuilder.AppendJoin.cs + TextTemplatingFileGenerator TextMeshProExtensions.cs @@ -95,6 +99,11 @@ True PreparedFormat.tt + + True + True + StringBuilder.AppendJoin.tt + True True diff --git a/tests/ZString.Tests/AppendJoinTest.cs b/tests/ZString.Tests/AppendJoinTest.cs new file mode 100644 index 00000000..918cf28f --- /dev/null +++ b/tests/ZString.Tests/AppendJoinTest.cs @@ -0,0 +1,213 @@ +using Cysharp.Text; +using FluentAssertions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public class AppendJoinTest + { +#if NETCOREAPP || NETSTANDARD2_1 + [Fact] + public void JoinOverloads() + { + var zsb = ZString.CreateStringBuilder(); + var bcl = new StringBuilder(); + zsb.Append("Foo:"); + bcl.Append("Foo:"); + + zsb.AppendJoin("_,_", 0); // params + bcl.AppendJoin("_,_", 0); // params + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", 0, 1); // params + bcl.AppendJoin("_,_", 0, 1); // params + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", new string[0]); + bcl.AppendJoin("_,_", new string[0]); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", new[] { 1, 2, 3 }); + bcl.AppendJoin("_,_", new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", new string[] { }.AsEnumerable()); + bcl.AppendJoin("_,_", new string[] { }.AsEnumerable()); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", new[] { 1, 2, 3 }.AsEnumerable()); + bcl.AppendJoin("_,_", new[] { 1, 2, 3 }.AsEnumerable()); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', new string[0]); + bcl.AppendJoin(',', new string[0]); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', new[] { 1, 2, 3 }); + bcl.AppendJoin(',', new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', new string[0].AsEnumerable()); + bcl.AppendJoin(',', new string[0].AsEnumerable()); + zsb.ToString().Should().Be(bcl.ToString()); + } + + [Fact] + public void JoinOverloads2() + { + var zsb = ZString.CreateStringBuilder(); + var bcl = new StringBuilder(); + zsb.Append("Foo:"); + bcl.Append("Foo:"); + + zsb.AppendJoin("_,_", new string[] { }.ToList()); + bcl.AppendJoin("_,_", new string[] { }.ToList()); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", new[] { 1, 2, 3 }.ToList()); + bcl.AppendJoin("_,_", new[] { 1, 2, 3 }.ToList()); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", (IList)new int[] { }); + bcl.AppendJoin("_,_", (IList)new int[] { }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", (IList)new[] { 1, 2, 3 }); + bcl.AppendJoin("_,_", (IList)new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", (IReadOnlyList)new int[] { }); + bcl.AppendJoin("_,_", (IReadOnlyList)new int[] { }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", (IReadOnlyList)new[] { 1, 2, 3 }); + bcl.AppendJoin("_,_", (IReadOnlyList)new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", (ICollection)new int[] { }); + bcl.AppendJoin("_,_", (ICollection)new int[] { }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", (ICollection)new[] { 1, 2, 3 }); + bcl.AppendJoin("_,_", (ICollection)new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", (IReadOnlyCollection)new int[] { }); + bcl.AppendJoin("_,_", (IReadOnlyCollection)new int[] { }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin("_,_", (IReadOnlyCollection)new[] { 1, 2, 3 }); + bcl.AppendJoin("_,_", (IReadOnlyCollection)new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + } + + [Fact] + public void JoinOverloads3() + { + var zsb = ZString.CreateStringBuilder(); + var bcl = new StringBuilder(); + zsb.Append("Foo:"); + bcl.Append("Foo:"); + + zsb.AppendJoin(',', new string[] { }.ToList()); + bcl.AppendJoin(',', new string[] { }.ToList()); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', new[] { 1, 2, 3 }.ToList()); + bcl.AppendJoin(',', new[] { 1, 2, 3 }.ToList()); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', (IList)new int[] { }); + bcl.AppendJoin(',', (IList)new int[] { }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', (IList)new[] { 1, 2, 3 }); + bcl.AppendJoin(',', (IList)new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', (IReadOnlyList)new int[] { }); + bcl.AppendJoin(',', (IReadOnlyList)new int[] { }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', (IReadOnlyList)new[] { 1, 2, 3 }); + bcl.AppendJoin(',', (IReadOnlyList)new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', (ICollection)new int[] { }); + bcl.AppendJoin(',', (ICollection)new int[] { }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', (ICollection)new[] { 1, 2, 3 }); + bcl.AppendJoin(',', (ICollection)new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', (IReadOnlyCollection)new int[] { }); + bcl.AppendJoin(',', (IReadOnlyCollection)new int[] { }); + zsb.ToString().Should().Be(bcl.ToString()); + + zsb.AppendJoin(',', (IReadOnlyCollection)new[] { 1, 2, 3 }); + bcl.AppendJoin(',', (IReadOnlyCollection)new[] { 1, 2, 3 }); + zsb.ToString().Should().Be(bcl.ToString()); + } + + [Fact] + public void JoinStrings() + { + var values = new string[] { "abc", null, "def" }; + { + const char sep = ','; + var zsb = ZString.CreateStringBuilder(); + var bcl = new StringBuilder(); + + zsb.AppendJoin(sep, "Foo:"); + bcl.AppendJoin(sep, "Foo:"); + + zsb.AppendJoin(sep, new ReadOnlySpan(values)); + bcl.AppendJoin(sep, values); + + zsb.AppendJoin(sep, values); + bcl.AppendJoin(sep, values); + + zsb.AppendJoin(sep, values.ToList()); + bcl.AppendJoin(sep, values.ToList()); + + zsb.AppendJoin(sep, values.AsEnumerable()); + bcl.AppendJoin(sep, values.AsEnumerable()); + + zsb.AppendLine(); + bcl.AppendLine(); + zsb.ToString().Should().Be(bcl.ToString()); + } + + { + const string sep = "_,_"; + var zsb = ZString.CreateStringBuilder(); + var bcl = new StringBuilder(); + + zsb.AppendJoin(sep, "Foo:"); + bcl.AppendJoin(sep, "Foo:"); + + zsb.AppendJoin(sep, new ReadOnlySpan(values)); + bcl.AppendJoin(sep, values); + + zsb.AppendJoin(sep, values); + bcl.AppendJoin(sep, values); + + zsb.AppendJoin(sep, values.ToList()); + bcl.AppendJoin(sep, values.ToList()); + + zsb.AppendJoin(sep, values.AsEnumerable()); + bcl.AppendJoin(sep, values.AsEnumerable()); + + zsb.AppendLine(); + bcl.AppendLine(); + zsb.ToString().Should().Be(bcl.ToString()); + } + } + } +#endif +} From 6a301ba3b91f1dfa3483241fb43a30119d6d0d8b Mon Sep 17 00:00:00 2001 From: udaken Date: Thu, 30 Jul 2020 22:18:29 +0900 Subject: [PATCH 069/139] update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1c147ae2..e253478c 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ Reference | Dispose() | void | Return the inner buffer to pool. | | `Append(T value)` | void | Appends the string representation of a specified value to this instance. | | `Append(T value, string format)` | void | Appends the string representation of a specified value to this instance with numeric format strings. | +| `AppendJoin(char/string, T[]/IE)`| void | Concatenates and appends the elements of an array, using the specified seperator between each element. | | `AppendLine()` | void | Appends the default line terminator to the end of this instance. | | `AppendLine(T value)` | void | Appends the string representation of a specified value followed by the default line terminator to the end of this instance. | | `AppendLine(T value, string format)` | void | Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. | @@ -141,6 +142,7 @@ Reference | Dispose() | void | Return the inner buffer to pool. | | `Append(T value)` | void | Appends the string representation of a specified value to this instance. | | `Append(T value, StandardFormat format)` | void | Appends the string representation of a specified value to this instance with numeric format strings. | +| `AppendJoin(char/string, T[]/IE)`| void | Concatenates and appends the elements of an array, using the specified seperator between each element. | | `AppendLine()` | void | Appends the default line terminator to the end of this instance. | | `AppendLine(T value)` | void | Appends the string representation of a specified value followed by the default line terminator to the end of this instance. | | `AppendLine(T value, StandardFormat format)` | void | Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. | From 8fb8adb4fc3aab00d304e291f114ce6ea695d3d2 Mon Sep 17 00:00:00 2001 From: udaken Date: Mon, 20 Jul 2020 00:38:09 +0900 Subject: [PATCH 070/139] Add Test with Unicode Text --- tests/ZString.Tests/FormatTest.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index ae32d52c..871080c0 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -106,5 +106,11 @@ public void Escape() var actual = ZString.Format(@"{0:h\,h\:mm\:ss}", span); actual.Should().Be(reference); } + + [Fact] + public void Unicode() + { + Test("\u30cf\u30fc\u30c8: {0}, \u5bb6\u65cf: {1}(\u7d75\u6587\u5b57)", "\u2764", "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67"); + } } } \ No newline at end of file From 487deb333e2c9e2804c9f99a804a2252fcae8d3d Mon Sep 17 00:00:00 2001 From: udaken Date: Mon, 20 Jul 2020 00:43:23 +0900 Subject: [PATCH 071/139] fix Utf8PreparedFormat --- .../Assets/Scripts/ZString/PreparedFormat.cs | 243 ++++++++---------- src/ZString/PreparedFormat.cs | 243 ++++++++---------- src/ZString/PreparedFormat.tt | 17 +- 3 files changed, 235 insertions(+), 268 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs index c5c66d2a..c343a572 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs @@ -1,5 +1,4 @@ - -using System; +using System; using System.Text; using System.Buffers; @@ -45,13 +44,13 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -121,13 +120,13 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -212,13 +211,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -318,13 +317,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -439,13 +438,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -575,13 +574,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -726,13 +725,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -892,13 +891,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1073,13 +1072,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1269,13 +1268,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1480,13 +1479,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1706,13 +1705,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1947,13 +1946,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -2203,13 +2202,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -2474,13 +2473,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -2760,13 +2759,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -3027,7 +3026,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3043,7 +3041,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1) @@ -3063,14 +3060,15 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3105,7 +3103,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3121,7 +3118,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2) @@ -3141,14 +3137,15 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3198,7 +3195,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3214,7 +3210,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3) @@ -3234,14 +3229,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3306,7 +3302,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3322,7 +3317,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) @@ -3342,14 +3336,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3429,7 +3424,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3445,7 +3439,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) @@ -3465,14 +3458,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3567,7 +3561,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3583,7 +3576,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) @@ -3603,14 +3595,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3720,7 +3713,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3736,7 +3728,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) @@ -3756,14 +3747,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3888,7 +3880,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3904,7 +3895,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) @@ -3924,14 +3914,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4071,7 +4062,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4269,7 +4259,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4482,7 +4471,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4710,7 +4698,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4953,7 +4940,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -5211,7 +5197,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -5484,7 +5469,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -5772,7 +5756,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { diff --git a/src/ZString/PreparedFormat.cs b/src/ZString/PreparedFormat.cs index c5c66d2a..c343a572 100644 --- a/src/ZString/PreparedFormat.cs +++ b/src/ZString/PreparedFormat.cs @@ -1,5 +1,4 @@ - -using System; +using System; using System.Text; using System.Buffers; @@ -45,13 +44,13 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -121,13 +120,13 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -212,13 +211,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -318,13 +317,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -439,13 +438,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -575,13 +574,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -726,13 +725,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -892,13 +891,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1073,13 +1072,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1269,13 +1268,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1480,13 +1479,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1706,13 +1705,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -1947,13 +1946,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -2203,13 +2202,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -2474,13 +2473,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -2760,13 +2759,13 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { - var strSpan = FormatString.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); } else @@ -3027,7 +3026,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3043,7 +3041,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1) @@ -3063,14 +3060,15 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3105,7 +3103,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3121,7 +3118,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2) @@ -3141,14 +3137,15 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3198,7 +3195,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3214,7 +3210,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3) @@ -3234,14 +3229,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3306,7 +3302,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3322,7 +3317,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) @@ -3342,14 +3336,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3429,7 +3424,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3445,7 +3439,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) @@ -3465,14 +3458,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3567,7 +3561,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3583,7 +3576,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) @@ -3603,14 +3595,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3720,7 +3713,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3736,7 +3728,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) @@ -3756,14 +3747,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -3888,7 +3880,6 @@ public sealed partial class Utf8PreparedFormat public int MinSize { get; } readonly FormatSegment[] segments; - readonly byte[] utf8Format; public Utf8PreparedFormat(string format) { @@ -3904,7 +3895,6 @@ public Utf8PreparedFormat(string format) } } this.MinSize = size; - this.utf8Format = Encoding.UTF8.GetBytes(format); } public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) @@ -3924,14 +3914,15 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4071,7 +4062,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4269,7 +4259,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4482,7 +4471,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4710,7 +4698,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -4953,7 +4940,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -5211,7 +5197,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -5484,7 +5469,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { @@ -5772,7 +5756,6 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { - var strSpan = utf8Format.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { - var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); - sb.Advance(item.Count); + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); } else { diff --git a/src/ZString/PreparedFormat.tt b/src/ZString/PreparedFormat.tt index edfd098f..4087bea3 100644 --- a/src/ZString/PreparedFormat.tt +++ b/src/ZString/PreparedFormat.tt @@ -19,9 +19,6 @@ namespace Cysharp.Text public int MinSize { get; } readonly FormatSegment[] segments; -<# if(!isUtf16) { #> - readonly byte[] utf8Format; -<# } #> public <#= utf #>PreparedFormat(string format) { @@ -37,9 +34,6 @@ namespace Cysharp.Text } } this.MinSize = size; -<# if(!isUtf16) { #> - this.utf8Format = Encoding.UTF8.GetBytes(format); -<# } #> } public string Format(<#= CreateParameters(i) #>) @@ -59,14 +53,21 @@ namespace Cysharp.Text public void FormatTo(ref TBufferWriter sb, <#= CreateParameters(i) #>) where TBufferWriter : IBufferWriter<<#= isUtf16 ? "char" : "byte" #>> { - var strSpan = <#= isUtf16 ? "FormatString" : "utf8Format" #>.AsSpan(); foreach (var item in segments) { if (!item.IsFormatArgument) { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); +<# if(isUtf16) { #> var span = sb.GetSpan(item.Count); - strSpan.Slice(item.Offset, item.Count).TryCopyTo(span); + strSpan.TryCopyTo(span); sb.Advance(item.Count); +<# } else { #> + var size = Encoding.UTF8.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Encoding.UTF8.GetBytes(strSpan, span); + sb.Advance(count); +<# } #> } else { From 655c3604da70541a7991170603d4a8874c5e0b37 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 1 Aug 2020 17:31:36 +0900 Subject: [PATCH 072/139] ReRun T4 Text Templates Tool on VS2019(16.6.5) --- src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs | 3 +-- .../ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs | 3 +-- src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs | 3 +-- src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs | 3 +-- src/ZString/PreparedFormat.cs | 3 +-- src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs | 3 +-- src/ZString/ZString.Format.cs | 3 +-- src/ZString/ZString.Utf8Format.cs | 3 +-- 8 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs index c5c66d2a..4759b589 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs @@ -1,5 +1,4 @@ - -using System; +using System; using System.Text; using System.Buffers; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index f023a822..634c583b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -1,5 +1,4 @@ - -using System; +using System; namespace Cysharp.Text { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs index 8eb89a1b..294862ca 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Format.cs @@ -1,5 +1,4 @@ - -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; namespace Cysharp.Text { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs index 60d49dcf..dcf7f395 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs @@ -1,5 +1,4 @@ - -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Buffers; using System; diff --git a/src/ZString/PreparedFormat.cs b/src/ZString/PreparedFormat.cs index c5c66d2a..4759b589 100644 --- a/src/ZString/PreparedFormat.cs +++ b/src/ZString/PreparedFormat.cs @@ -1,5 +1,4 @@ - -using System; +using System; using System.Text; using System.Buffers; diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index f023a822..634c583b 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -1,5 +1,4 @@ - -using System; +using System; namespace Cysharp.Text { diff --git a/src/ZString/ZString.Format.cs b/src/ZString/ZString.Format.cs index 8eb89a1b..294862ca 100644 --- a/src/ZString/ZString.Format.cs +++ b/src/ZString/ZString.Format.cs @@ -1,5 +1,4 @@ - -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; namespace Cysharp.Text { diff --git a/src/ZString/ZString.Utf8Format.cs b/src/ZString/ZString.Utf8Format.cs index 60d49dcf..dcf7f395 100644 --- a/src/ZString/ZString.Utf8Format.cs +++ b/src/ZString/ZString.Utf8Format.cs @@ -1,5 +1,4 @@ - -using System.Runtime.CompilerServices; +using System.Runtime.CompilerServices; using System.Buffers; using System; From 1ff7e56a0ca2ba4c8fa6b919fae15a86e9608850 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 1 Aug 2020 17:32:37 +0900 Subject: [PATCH 073/139] Code cleanup --- ...Utf16ValueStringBuilder.CreateFormatter.cs | 52 +++++++++---------- ...alueStringBuilder.SpanFormattableAppend.cs | 2 +- ...alueStringBuilder.SpanFormattableAppend.cs | 2 +- ...Utf16ValueStringBuilder.CreateFormatter.cs | 52 +++++++++---------- ...Utf16ValueStringBuilder.CreateFormatter.tt | 5 +- ...alueStringBuilder.SpanFormattableAppend.cs | 2 +- ...alueStringBuilder.SpanFormattableAppend.tt | 2 +- .../Utf8ValueStringBuilder.AppendFormat.tt | 2 +- ...alueStringBuilder.SpanFormattableAppend.cs | 2 +- ...alueStringBuilder.SpanFormattableAppend.tt | 2 +- 10 files changed, 62 insertions(+), 61 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index b02bca8e..8d939c70 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -66,61 +66,61 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(System.SByte?)) + if (type == typeof(System.Byte?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Int16?)) + if (type == typeof(System.DateTime?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Int32?)) + if (type == typeof(System.DateTimeOffset?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Int64?)) + if (type == typeof(System.Decimal?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Byte?)) + if (type == typeof(System.Double?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.UInt16?)) + if (type == typeof(System.Int16?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.UInt32?)) + if (type == typeof(System.Int32?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.UInt64?)) + if (type == typeof(System.Int64?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Single?)) + if (type == typeof(System.SByte?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Double?)) + if (type == typeof(System.Single?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } if (type == typeof(System.TimeSpan?)) { return CreateNullableFormatter(); } - if (type == typeof(System.DateTime?)) + if (type == typeof(System.UInt16?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.DateTimeOffset?)) + if (type == typeof(System.UInt32?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Decimal?)) + if (type == typeof(System.UInt64?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } if (type == typeof(System.Guid?)) { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index bdf6e179..39009e31 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -4,7 +4,7 @@ namespace Cysharp.Text { public partial struct Utf16ValueStringBuilder - { + { /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index a79d0c39..1a46010b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -6,7 +6,7 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder - { + { /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index b02bca8e..8d939c70 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -66,61 +66,61 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Guid x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } - if (type == typeof(System.SByte?)) + if (type == typeof(System.Byte?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Int16?)) + if (type == typeof(System.DateTime?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Int32?)) + if (type == typeof(System.DateTimeOffset?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Int64?)) + if (type == typeof(System.Decimal?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Byte?)) + if (type == typeof(System.Double?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.UInt16?)) + if (type == typeof(System.Int16?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.UInt32?)) + if (type == typeof(System.Int32?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.UInt64?)) + if (type == typeof(System.Int64?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Single?)) + if (type == typeof(System.SByte?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Double?)) + if (type == typeof(System.Single?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } if (type == typeof(System.TimeSpan?)) { return CreateNullableFormatter(); } - if (type == typeof(System.DateTime?)) + if (type == typeof(System.UInt16?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.DateTimeOffset?)) + if (type == typeof(System.UInt32?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } - if (type == typeof(System.Decimal?)) + if (type == typeof(System.UInt64?)) { - return CreateNullableFormatter(); + return CreateNullableFormatter(); } if (type == typeof(System.Guid?)) { diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt index 829856fc..0ccd7055 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt @@ -4,6 +4,7 @@ <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> +<#@ include file="../T4Common.t4" once="true" #> <# var spanFormattablesA = new Type[] { @@ -56,13 +57,13 @@ namespace Cysharp.Text return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } <# } #> -<# foreach(var t in spanFormattablesA.Concat(spanFormattablesB).Concat(spanFormattablesC)) { #> +<# foreach(var t in spanFormattables) { #> if (type == typeof(<#= t.FullName #>?)) { return CreateNullableFormatter<<#= t.FullName #>>(); } <# } #> -<# foreach(var t in new [] {typeof(IntPtr), typeof(UIntPtr)} ) { var u = t == typeof(UIntPtr); #> +<# foreach(var t in new [] {typeof(IntPtr), typeof(UIntPtr)}) { var u = t == typeof(UIntPtr); #> if (type == typeof(<#= t.FullName #>)) { // ignore format diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs index bdf6e179..39009e31 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.cs @@ -4,7 +4,7 @@ namespace Cysharp.Text { public partial struct Utf16ValueStringBuilder - { + { /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt index 0189dc34..9464f38e 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.SpanFormattableAppend.tt @@ -11,7 +11,7 @@ using System.Runtime.CompilerServices; namespace Cysharp.Text { public partial struct Utf16ValueStringBuilder - { + { <# foreach(var t in spanFormattables) { #> /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt index ec591ee3..c556378d 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt @@ -3,8 +3,8 @@ <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Collections.Generic" #> -<#@ include file="../T4Common.t4" once="true" #> <#@ output extension=".cs" #> +<#@ include file="../T4Common.t4" once="true" #> using System; using System.Buffers; diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index a79d0c39..1a46010b 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -6,7 +6,7 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder - { + { /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Byte value) diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt index 7bc13892..819f2114 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt @@ -13,7 +13,7 @@ using System.Runtime.CompilerServices; namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder - { + { <# foreach(var t in spanFormattables) { #> /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] From ae8b64679b979d796c55498605bf3575e1e74324 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 1 Aug 2020 17:37:40 +0900 Subject: [PATCH 074/139] Make ignored BenchmarkDotNet Results --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index abc89380..2449b426 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,6 @@ src/ZString.Unity/ZString.csproj src/ZString.Unity/ZString.Unity.sln src/ZString.Unity/ZString.Unity.unitypackage + +# Benchmark Results +**/BenchmarkDotNet.Artifacts/* From e1780cc9c48368180e5718a0601d6cb424dbc657 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 1 Aug 2020 17:46:51 +0900 Subject: [PATCH 075/139] Bump up BenchmarkDotNet to v0.12.1 --- sandbox/PerfBenchmark/PerfBenchmark.csproj | 2 +- sandbox/PerfBenchmark/Program.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sandbox/PerfBenchmark/PerfBenchmark.csproj b/sandbox/PerfBenchmark/PerfBenchmark.csproj index 6cb78ecb..03fed0f4 100644 --- a/sandbox/PerfBenchmark/PerfBenchmark.csproj +++ b/sandbox/PerfBenchmark/PerfBenchmark.csproj @@ -6,7 +6,7 @@ - + diff --git a/sandbox/PerfBenchmark/Program.cs b/sandbox/PerfBenchmark/Program.cs index 1a8fbebc..1563d617 100644 --- a/sandbox/PerfBenchmark/Program.cs +++ b/sandbox/PerfBenchmark/Program.cs @@ -16,8 +16,8 @@ internal class BenchmarkConfig : ManualConfig { public BenchmarkConfig() { - Add(MemoryDiagnoser.Default); - Add(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1)); + AddDiagnoser(MemoryDiagnoser.Default); + AddJob(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1)); } } From 03e0f4a72b44ba448d4e00eb00dfff189eaf174d Mon Sep 17 00:00:00 2001 From: udaken Date: Mon, 20 Jul 2020 07:14:33 +0900 Subject: [PATCH 076/139] Add BenchmarkVsReleasedVersion project --- ZString.sln | 7 +- .../BenchmarkVsReleasedVersion.csproj | 22 +++ .../BuiltinTypesBenchmark.cs | 175 ++++++++++++++++++ .../ConcatBenchmark.cs | 103 +++++++++++ .../FormatBenchmark.cs | 132 +++++++++++++ .../MaximumArgsFormatBenchmark.cs | 134 ++++++++++++++ sandbox/BenchmarkVsReleasedVersion/Program.cs | 33 ++++ sandbox/BenchmarkVsReleasedVersion/runall.cmd | 1 + 8 files changed, 606 insertions(+), 1 deletion(-) create mode 100644 sandbox/BenchmarkVsReleasedVersion/BenchmarkVsReleasedVersion.csproj create mode 100644 sandbox/BenchmarkVsReleasedVersion/BuiltinTypesBenchmark.cs create mode 100644 sandbox/BenchmarkVsReleasedVersion/ConcatBenchmark.cs create mode 100644 sandbox/BenchmarkVsReleasedVersion/FormatBenchmark.cs create mode 100644 sandbox/BenchmarkVsReleasedVersion/MaximumArgsFormatBenchmark.cs create mode 100644 sandbox/BenchmarkVsReleasedVersion/Program.cs create mode 100644 sandbox/BenchmarkVsReleasedVersion/runall.cmd diff --git a/ZString.sln b/ZString.sln index 5f56468f..4897f7f9 100644 --- a/ZString.sln +++ b/ZString.sln @@ -27,7 +27,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppNet472", "sandbox EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZString.NetCore2Tests", "tests\ZString.NetCore2Tests\ZString.NetCore2Tests.csproj", "{62C44156-F55C-4006-B9A2-108DAB340FAC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PerfBenchmark", "sandbox\PerfBenchmark\PerfBenchmark.csproj", "{D766AEB3-3609-4F1D-8D81-5549F748F372}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PerfBenchmark", "sandbox\PerfBenchmark\PerfBenchmark.csproj", "{D766AEB3-3609-4F1D-8D81-5549F748F372}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkVsReleasedVersion", "sandbox\BenchmarkVsReleasedVersion\BenchmarkVsReleasedVersion.csproj", "{94F4D0E1-25FA-4C83-B11A-098754D5554F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -59,6 +61,8 @@ Global {D766AEB3-3609-4F1D-8D81-5549F748F372}.Debug|Any CPU.Build.0 = Debug|Any CPU {D766AEB3-3609-4F1D-8D81-5549F748F372}.Release|Any CPU.ActiveCfg = Release|Any CPU {D766AEB3-3609-4F1D-8D81-5549F748F372}.Release|Any CPU.Build.0 = Release|Any CPU + {94F4D0E1-25FA-4C83-B11A-098754D5554F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {94F4D0E1-25FA-4C83-B11A-098754D5554F}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -70,6 +74,7 @@ Global {BE8A17AA-504A-410D-B86D-92431B0F5594} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} {62C44156-F55C-4006-B9A2-108DAB340FAC} = {0803618F-C4E8-4D37-831E-5D26C5574F49} {D766AEB3-3609-4F1D-8D81-5549F748F372} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} + {94F4D0E1-25FA-4C83-B11A-098754D5554F} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DF39BF43-3E0E-4F7D-9943-7E50D301234D} diff --git a/sandbox/BenchmarkVsReleasedVersion/BenchmarkVsReleasedVersion.csproj b/sandbox/BenchmarkVsReleasedVersion/BenchmarkVsReleasedVersion.csproj new file mode 100644 index 00000000..7e34c82c --- /dev/null +++ b/sandbox/BenchmarkVsReleasedVersion/BenchmarkVsReleasedVersion.csproj @@ -0,0 +1,22 @@ + + + + Exe + netcoreapp3.1 + + 8.0 + + + + + + + + + + + NewZString + + + + diff --git a/sandbox/BenchmarkVsReleasedVersion/BuiltinTypesBenchmark.cs b/sandbox/BenchmarkVsReleasedVersion/BuiltinTypesBenchmark.cs new file mode 100644 index 00000000..20b8ab4d --- /dev/null +++ b/sandbox/BenchmarkVsReleasedVersion/BuiltinTypesBenchmark.cs @@ -0,0 +1,175 @@ +// Before use, You must change AssemblyName to "NewZString" of local ZString.csproj + +extern alias NewZString; + +using System; +using System.Collections.Generic; +using System.Text; +using Cysharp.Text; +using NZString = NewZString::Cysharp.Text.ZString; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; + +using PF16 = Cysharp.Text.Utf16PreparedFormat; +using NPF16 = NewZString::Cysharp.Text.Utf16PreparedFormat; + +using PF8 = Cysharp.Text.Utf8PreparedFormat; +using NPF8 = NewZString::Cysharp.Text.Utf8PreparedFormat; + +namespace BenchmarkVsReleasedVersion +{ + [Config(typeof(BenchmarkConfig))] + [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + [DisassemblyDiagnoser] + public class BuiltinTypesBenchmark + { + string _format; + + byte _byte; + DateTime _dt; + DateTimeOffset _dto; + decimal _decimal; + double _double; + Guid _guid; + short _short; + sbyte _sbyte; + float _float; + TimeSpan _ts; + ushort _ushort; + uint _uint; + ulong _ulong; + object _null; + string _string; + bool _bool; + TypeCode _enum; + char _char; + + PF16 _utf16preparedFormat_; + NPF16 _utf16preparedFormatN; + + PF8 _utf8preparedFormat_; + NPF8 _utf8preparedFormatN; + + public BuiltinTypesBenchmark() + { + var rand = new Random(); + + _format = "{0}-{1}-{2}-{3}-{4}-{5}-{6}-{7}-{8}-{9}-{10}-{11}-{12}-{13}-{14}-{15}"; + + _utf16preparedFormat_ = new PF16(_format); + _utf16preparedFormatN = new NPF16(_format); + + _utf8preparedFormat_ = new PF8(_format); + _utf8preparedFormatN = new NPF8(_format); + + _byte = (byte)rand.Next(); + _dt = DateTime.Now; + _dto = DateTimeOffset.Now; + _decimal = (decimal)rand.NextDouble(); + _double = rand.NextDouble(); + _guid = Guid.NewGuid(); + _short = (short)rand.Next(); + _sbyte = (sbyte)rand.Next(); + _float = (float)rand.NextDouble(); + _ts = DateTime.Now - DateTime.Today; + _ushort = (ushort)rand.Next(); + _uint = (uint)rand.Next(); + _ulong = (ulong)rand.Next(); + _null = null; + _string = Guid.NewGuid().ToString(); + _bool = rand.Next() % 1 == 0; + _enum = (TypeCode)rand.Next((int)TypeCode.DateTime); + _char = (char)rand.Next(); + } + + [BenchmarkCategory("Format"), Benchmark(Baseline = true)] + public string Format_() + { + return ZString.Format(_format, + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + } + + [BenchmarkCategory("Format"), Benchmark] + public string FormatN() + { + return NZString.Format(_format, + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + } + + [BenchmarkCategory("CreatePreparedFormat"), Benchmark(Baseline = true)] + public object CreatePreparedFormat_() + { + return new PF16(_format); + } + + [BenchmarkCategory("CreatePreparedFormat"), Benchmark] + public object CreatePreparedFormatN() + { + return new NPF16(_format); + } + + [BenchmarkCategory("Utf16PreparedFormat"), Benchmark(Baseline = true)] + public string Utf16PreparedFormat_() + { + return _utf16preparedFormat_.Format( + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + } + + [BenchmarkCategory("Utf16PreparedFormat"), Benchmark] + public string Utf16PreparedFormatN() + { + return _utf16preparedFormatN.Format( + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + } + + [BenchmarkCategory("Utf8PreparedFormat"), Benchmark(Baseline = true)] + public string Utf8PreparedFormat_() + { + return _utf8preparedFormat_.Format( + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + } + + [BenchmarkCategory("Utf8PreparedFormat"), Benchmark] + public string Utf8PreparedFormatN() + { + return _utf8preparedFormatN.Format( + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + } + + [BenchmarkCategory("Utf16StringBuilderAppendFormat"), Benchmark(Baseline = true)] + public int Utf16StringBuilderAppendFormat_() + { + using var zsh = ZString.CreateStringBuilder(); + zsh.AppendFormat(_format, + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + return zsh.Length; + } + + [BenchmarkCategory("Utf16StringBuilderAppendFormat"), Benchmark] + public int Utf16StringBuilderAppendFormatN() + { + using var zsh = NZString.CreateStringBuilder(); + zsh.AppendFormat(_format, + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + return zsh.Length; + } + + [BenchmarkCategory("Utf8StringBuilderAppendFormat"), Benchmark(Baseline = true)] + public int Utf8StringBuilderAppendFormat_() + { + using var zsh = ZString.CreateUtf8StringBuilder(); + zsh.AppendFormat(_format, + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + return zsh.Length; + } + + [BenchmarkCategory("Utf8StringBuilderAppendFormat"), Benchmark] + public int Utf8StringBuilderAppendFormatN() + { + using var zsh = NZString.CreateUtf8StringBuilder(); + zsh.AppendFormat(_format, + _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); + return zsh.Length; + } + } +} diff --git a/sandbox/BenchmarkVsReleasedVersion/ConcatBenchmark.cs b/sandbox/BenchmarkVsReleasedVersion/ConcatBenchmark.cs new file mode 100644 index 00000000..9c9c51e4 --- /dev/null +++ b/sandbox/BenchmarkVsReleasedVersion/ConcatBenchmark.cs @@ -0,0 +1,103 @@ +extern alias NewZString; + +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using Cysharp.Text; +using System; +using System.Text; + +namespace BenchmarkVsReleasedVersion +{ + [Config(typeof(BenchmarkConfig))] + [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + [DisassemblyDiagnoser(maxDepth: 3)] + public class ConcatBenchmark + { + int a; + int b; + int c; + int x; + int y; + int z; + + public ConcatBenchmark() + { + a = int.Parse("000"); + b = int.Parse("111"); + c = int.Parse("222"); + x = int.Parse("333"); + y = int.Parse("444"); + z = int.Parse("555"); + } + + [BenchmarkCategory("FourParams"), Benchmark(Baseline = true)] + public string FourParamsConcat_() + { + return ZString + .Concat("x:", x, " y:", y); + } + + [BenchmarkCategory("FourParams"), Benchmark] + public string FourParamsConcatN() + { + return NewZString::Cysharp.Text.ZString + .Concat("x:", x, " y:", y); + } + + [BenchmarkCategory("SixParams"), Benchmark(Baseline = true)] + public string SixParamsConcat_() + { + return ZString + .Concat("a:", a, " b:", b, " c:", c); + } + + [BenchmarkCategory("SixParams"), Benchmark] + public string SixParamsConcatN() + { + return NewZString::Cysharp.Text.ZString + .Concat("a:", a, " b:", b, " c:", c); + } + + [BenchmarkCategory("EightParams"), Benchmark(Baseline = true)] + public string EightParamsConcat_() + { + return ZString + .Concat("a:", a, " b:", b, " c:", c, " x:", x); + } + + [BenchmarkCategory("EightParams"), Benchmark] + public string EightParamsConcatN() + { + return NewZString::Cysharp.Text.ZString + .Concat("a:", a, " b:", b, " c:", c, " x:", x); + } + + [BenchmarkCategory("TenParams"), Benchmark(Baseline = true)] + public string TenParamsConcat_() + { + return ZString + .Concat("a:", a, " b:", b, " c:", c, " x:", x, " y:", y); + } + + [BenchmarkCategory("TenParams"), Benchmark] + public string TenParamsConcatN() + { + return NewZString::Cysharp.Text.ZString + .Concat("a:", a, " b:", b, " c:", c, " x:", x, " y:", y); + } + + [BenchmarkCategory("TwelveParams"), Benchmark(Baseline = true)] + public string TwelveParamsConcat_() + { + return ZString + .Concat("a:", a, " b:", b, " c:", c, " x:", x, " y:", y, " z:", z); + } + + [BenchmarkCategory("TwelveParams"), Benchmark] + public string TwelveParamsConcatN() + { + return NewZString::Cysharp.Text.ZString + .Concat("a:", a, " b:", b, " c:", c, " x:", x, " y:", y, " z:", z); + } + } +} diff --git a/sandbox/BenchmarkVsReleasedVersion/FormatBenchmark.cs b/sandbox/BenchmarkVsReleasedVersion/FormatBenchmark.cs new file mode 100644 index 00000000..14a49c20 --- /dev/null +++ b/sandbox/BenchmarkVsReleasedVersion/FormatBenchmark.cs @@ -0,0 +1,132 @@ +// Before use, You must change AssemblyName to "NewZString" of local ZString.csproj + +extern alias NewZString; + +using System; +using System.Collections.Generic; +using System.Text; +using Cysharp.Text; +using NZString = NewZString::Cysharp.Text.ZString; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; + +namespace BenchmarkVsReleasedVersion +{ + [Config(typeof(BenchmarkConfig))] + [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + [DisassemblyDiagnoser(maxDepth:3)] + public class FormatBenchmark + { + int x; + int y; + + Utf16PreparedFormat _utf16preparedFormat_; + NewZString::Cysharp.Text.Utf16PreparedFormat _utf16preparedFormatN; + + Utf8PreparedFormat _utf8preparedFormat_; + NewZString::Cysharp.Text.Utf8PreparedFormat _utf8preparedFormatN; + + [Params( + "x:{0}, y:{1}", + "This is a test to see how{0} well {1}this does. Hello, world." + )] + public string FormatString { get; set; } + + [GlobalSetup] + public void GlobalSetup() + { + _utf16preparedFormat_ = new Utf16PreparedFormat(FormatString); + _utf16preparedFormatN = new NewZString::Cysharp.Text.Utf16PreparedFormat(FormatString); + + _utf8preparedFormat_ = new Utf8PreparedFormat(FormatString); + _utf8preparedFormatN = new NewZString::Cysharp.Text.Utf8PreparedFormat(FormatString); + } + + + public FormatBenchmark() + { + x = int.Parse("100"); + y = int.Parse("200"); + } + + [BenchmarkCategory("Format"), Benchmark(Baseline = true)] + public string Format_() + { + return ZString.Format(FormatString, x, y); + } + + [BenchmarkCategory("Format"), Benchmark] + public string FormatN() + { + return NZString.Format(FormatString, x, y); + } + + [BenchmarkCategory("CreatePreparedFormat"), Benchmark(Baseline = true)] + public object CreatePreparedFormat_() + { + return new Utf16PreparedFormat(FormatString); + } + + [BenchmarkCategory("CreatePreparedFormat"), Benchmark] + public object CreatePreparedFormatN() + { + return new NewZString::Cysharp.Text.Utf16PreparedFormat(FormatString); + } + + [BenchmarkCategory("Utf16PreparedFormat"), Benchmark(Baseline = true)] + public string Utf16PreparedFormat_() + { + return _utf16preparedFormat_.Format(x, y); + } + + [BenchmarkCategory("Utf16PreparedFormat"), Benchmark] + public string Utf16PreparedFormatN() + { + return _utf16preparedFormatN.Format(x, y); + } + + [BenchmarkCategory("Utf8PreparedFormat"), Benchmark(Baseline = true)] + public string Utf8PreparedFormat_() + { + return _utf8preparedFormat_.Format(x, y); + } + + [BenchmarkCategory("Utf8PreparedFormat"), Benchmark] + public string Utf8PreparedFormatN() + { + return _utf8preparedFormatN.Format(x, y); + } + + [BenchmarkCategory("Utf16StringBuilderAppendFormat"), Benchmark(Baseline = true)] + public int Utf16StringBuilderAppendFormat_() + { + using var zsh = ZString.CreateStringBuilder(); + zsh.AppendFormat(FormatString, x, y); + return zsh.Length; + } + + [BenchmarkCategory("Utf16StringBuilderAppendFormat"), Benchmark] + public int Utf16StringBuilderAppendFormatN() + { + using var zsh = NZString.CreateStringBuilder(); + zsh.AppendFormat(FormatString, x, y); + return zsh.Length; + } + + [BenchmarkCategory("Utf8StringBuilderAppendFormat"), Benchmark(Baseline = true)] + public int Utf8StringBuilderAppendFormat_() + { + using var zsh = ZString.CreateUtf8StringBuilder(); + zsh.AppendFormat(FormatString, x, y); + return zsh.Length; + } + + [BenchmarkCategory("Utf8StringBuilderAppendFormat"), Benchmark] + public int Utf8StringBuilderAppendFormatN() + { + using var zsh = NZString.CreateUtf8StringBuilder(); + zsh.AppendFormat(FormatString, x, y); + return zsh.Length; + } + } +} diff --git a/sandbox/BenchmarkVsReleasedVersion/MaximumArgsFormatBenchmark.cs b/sandbox/BenchmarkVsReleasedVersion/MaximumArgsFormatBenchmark.cs new file mode 100644 index 00000000..bee6532b --- /dev/null +++ b/sandbox/BenchmarkVsReleasedVersion/MaximumArgsFormatBenchmark.cs @@ -0,0 +1,134 @@ +// Before use, You must change AssemblyName to "NewZString" of local ZString.csproj + +extern alias NewZString; + +using System; +using System.Collections.Generic; +using System.Text; +using Cysharp.Text; +using NZString = NewZString::Cysharp.Text.ZString; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; + +using PF16 = Cysharp.Text.Utf16PreparedFormat; +using NPF16 = NewZString::Cysharp.Text.Utf16PreparedFormat; + +using PF8 = Cysharp.Text.Utf8PreparedFormat; +using NPF8 = NewZString::Cysharp.Text.Utf8PreparedFormat; + +namespace BenchmarkVsReleasedVersion +{ + [Config(typeof(BenchmarkConfig))] + [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + [DisassemblyDiagnoser(maxDepth: 3)] + public class MaximumArgsFormatBenchmark + { + readonly int[] _args; + + readonly string _format; + PF16 _utf16preparedFormat_; + NPF16 _utf16preparedFormatN; + + PF8 _utf8preparedFormat_; + NPF8 _utf8preparedFormatN; + + public MaximumArgsFormatBenchmark() + { + _args = new int[16]; + var rand = new Random(); + _format = "<"; + for (var i = 0; i < _args.Length; i++) + { + _args[i] = rand.Next(); + _format += "{" + i + "}, "; + } + _format += ">"; + + _utf16preparedFormat_ = new PF16(_format); + _utf16preparedFormatN = new NPF16(_format); + + _utf8preparedFormat_ = new PF8(_format); + _utf8preparedFormatN = new NPF8(_format); + } + + [BenchmarkCategory("Format"), Benchmark(Baseline = true)] + public string Format_() + { + return ZString.Format(_format, _args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + } + + [BenchmarkCategory("Format"), Benchmark] + public string FormatN() + { + return NZString.Format(_format, _args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + } + + [BenchmarkCategory("CreatePreparedFormat"), Benchmark(Baseline = true)] + public object CreatePreparedFormat_() + { + return new PF16(_format); + } + + [BenchmarkCategory("CreatePreparedFormat"), Benchmark] + public object CreatePreparedFormatN() + { + return new NPF16(_format); + } + + [BenchmarkCategory("Utf16PreparedFormat"), Benchmark(Baseline = true)] + public string Utf16PreparedFormat_() + { + return _utf16preparedFormat_.Format(_args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + } + + [BenchmarkCategory("Utf16PreparedFormat"), Benchmark] + public string Utf16PreparedFormatN() + { + return _utf16preparedFormatN.Format(_args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + } + + [BenchmarkCategory("Utf8PreparedFormat"), Benchmark(Baseline = true)] + public string Utf8PreparedFormat_() + { + return _utf8preparedFormat_.Format(_args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + } + + [BenchmarkCategory("Utf8PreparedFormat"), Benchmark] + public string Utf8PreparedFormatN() + { + return _utf8preparedFormatN.Format(_args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + } + + [BenchmarkCategory("Utf16StringBuilderAppendFormat"), Benchmark(Baseline = true)] + public int Utf16StringBuilderAppendFormat_() + { + using var zsh = ZString.CreateStringBuilder(); + zsh.AppendFormat(_format, _args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + return zsh.Length; + } + + [BenchmarkCategory("Utf16StringBuilderAppendFormat"), Benchmark] + public int Utf16StringBuilderAppendFormatN() + { + using var zsh = NZString.CreateStringBuilder(); + zsh.AppendFormat(_format, _args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + return zsh.Length; + } + + [BenchmarkCategory("Utf8StringBuilderAppendFormat"), Benchmark(Baseline = true)] + public int Utf8StringBuilderAppendFormat_() + { + using var zsh = ZString.CreateUtf8StringBuilder(); + zsh.AppendFormat(_format, _args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + return zsh.Length; + } + + [BenchmarkCategory("Utf8StringBuilderAppendFormat"), Benchmark] + public int Utf8StringBuilderAppendFormatN() + { + using var zsh = NZString.CreateUtf8StringBuilder(); + zsh.AppendFormat(_format, _args[0], _args[1], _args[2], _args[3], _args[4], _args[5], _args[6], _args[7], _args[8], _args[9], _args[10], _args[11], _args[12], _args[13], _args[14], _args[15]); + return zsh.Length; + } + } +} diff --git a/sandbox/BenchmarkVsReleasedVersion/Program.cs b/sandbox/BenchmarkVsReleasedVersion/Program.cs new file mode 100644 index 00000000..45ee6879 --- /dev/null +++ b/sandbox/BenchmarkVsReleasedVersion/Program.cs @@ -0,0 +1,33 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Environments; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Running; +using Cysharp.Text; +using System; +using System.Buffers; +using System.Reflection; +using System.Text; + +namespace BenchmarkVsReleasedVersion +{ + internal class BenchmarkConfig : ManualConfig + { + public BenchmarkConfig() + { + AddDiagnoser(MemoryDiagnoser.Default); + AddJob(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1)); + } + } + + public class Program + { + static void Main(string[] args) + { + BenchmarkSwitcher.FromAssembly(Assembly.GetEntryAssembly()).Run(args); + } + } +} diff --git a/sandbox/BenchmarkVsReleasedVersion/runall.cmd b/sandbox/BenchmarkVsReleasedVersion/runall.cmd new file mode 100644 index 00000000..3a03a8ea --- /dev/null +++ b/sandbox/BenchmarkVsReleasedVersion/runall.cmd @@ -0,0 +1 @@ +dotnet run -c Release --filter * From 6919046da03e140a6ab3a93ffe90e0928684209d Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 1 Aug 2020 23:16:08 +0900 Subject: [PATCH 077/139] Improved performance of StringBuilder.AppendFormat --- .../Utf16ValueStringBuilder.AppendFormat.cs | 2240 +++-------------- .../ZString/Utf16ValueStringBuilder.cs | 13 + .../Utf8ValueStringBuilder.AppendFormat.cs | 2160 +++------------- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 14 + .../Utf16ValueStringBuilder.AppendFormat.cs | 2240 +++-------------- .../Utf16ValueStringBuilder.AppendFormat.tt | 35 +- src/ZString/Utf16ValueStringBuilder.cs | 13 + .../Utf8ValueStringBuilder.AppendFormat.cs | 2160 +++------------- .../Utf8ValueStringBuilder.AppendFormat.tt | 30 +- src/ZString/Utf8ValueStringBuilder.cs | 14 + 10 files changed, 1410 insertions(+), 7509 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 634c583b..515186d2 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -21,9 +21,7 @@ public void AppendFormat(string format, T1 arg1) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -31,9 +29,7 @@ public void AppendFormat(string format, T1 arg1) else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -43,41 +39,24 @@ public void AppendFormat(string format, T1 arg1) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -85,9 +64,7 @@ public void AppendFormat(string format, T1 arg1) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -109,9 +86,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -119,9 +94,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -131,54 +104,27 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -186,9 +132,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -210,9 +154,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -220,9 +162,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -232,67 +172,30 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -300,9 +203,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -324,9 +225,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -334,9 +233,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -346,80 +243,33 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -427,9 +277,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -451,9 +299,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -461,9 +307,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -473,93 +317,36 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -567,9 +354,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -591,9 +376,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -601,9 +384,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -613,106 +394,39 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -720,9 +434,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -744,9 +456,7 @@ public void AppendFormat(string format, T1 arg1, T2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -754,9 +464,7 @@ public void AppendFormat(string format, T1 arg1, T2 else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -766,119 +474,42 @@ public void AppendFormat(string format, T1 arg1, T2 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -886,9 +517,7 @@ public void AppendFormat(string format, T1 arg1, T2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -910,9 +539,7 @@ public void AppendFormat(string format, T1 arg1, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -920,9 +547,7 @@ public void AppendFormat(string format, T1 arg1, else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -932,132 +557,45 @@ public void AppendFormat(string format, T1 arg1, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1065,9 +603,7 @@ public void AppendFormat(string format, T1 arg1, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1089,9 +625,7 @@ public void AppendFormat(string format, T1 a if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1099,9 +633,7 @@ public void AppendFormat(string format, T1 a else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1111,145 +643,48 @@ public void AppendFormat(string format, T1 a switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1257,9 +692,7 @@ public void AppendFormat(string format, T1 a var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1281,9 +714,7 @@ public void AppendFormat(string format, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1291,9 +722,7 @@ public void AppendFormat(string format, else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1303,158 +732,51 @@ public void AppendFormat(string format, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1462,9 +784,7 @@ public void AppendFormat(string format, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1486,9 +806,7 @@ public void AppendFormat(string fo if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1496,9 +814,7 @@ public void AppendFormat(string fo else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1508,171 +824,54 @@ public void AppendFormat(string fo switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1680,9 +879,7 @@ public void AppendFormat(string fo var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1704,9 +901,7 @@ public void AppendFormat(stri if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1714,9 +909,7 @@ public void AppendFormat(stri else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1726,184 +919,57 @@ public void AppendFormat(stri switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1911,9 +977,7 @@ public void AppendFormat(stri var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1935,9 +999,7 @@ public void AppendFormat if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1945,9 +1007,7 @@ public void AppendFormat else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1957,197 +1017,60 @@ public void AppendFormat switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -2155,9 +1078,7 @@ public void AppendFormat var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2179,9 +1100,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, indexParse.FormatString, nameof(arg14)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -2412,9 +1182,7 @@ public void AppendFormat 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2436,9 +1204,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, indexParse.FormatString, nameof(arg14)); + continue; case 14: - { - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg15, indexParse.FormatString, nameof(arg15)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -2682,9 +1289,7 @@ public void AppendFormat 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2706,9 +1311,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, indexParse.FormatString, nameof(arg14)); + continue; case 14: - { - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg15, indexParse.FormatString, nameof(arg15)); + continue; case 15: - { - if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg16)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg16, indexParse.FormatString, nameof(arg16)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -2965,9 +1399,7 @@ public void AppendFormat 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 96c5fbb6..7a4368a6 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -565,6 +565,19 @@ static void ThrowNestedException() throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); } + void AppendFormatInternal(T arg1, ReadOnlySpan format, string argName) + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, format)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(argName); + } + } + index += written; + } + /// /// Register custom formatter /// diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index a592f591..8fd66bc9 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -22,8 +22,7 @@ public void AppendFormat(string format, T1 arg1) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -31,8 +30,7 @@ public void AppendFormat(string format, T1 arg1) else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -43,39 +41,24 @@ public void AppendFormat(string format, T1 arg1) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -83,8 +66,7 @@ public void AppendFormat(string format, T1 arg1) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -106,8 +88,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -115,8 +96,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -127,52 +107,27 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -180,8 +135,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -203,8 +157,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -212,8 +165,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -224,65 +176,30 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -290,8 +207,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -313,8 +229,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -322,8 +237,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -334,78 +248,33 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -413,8 +282,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -436,8 +304,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -445,8 +312,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -457,91 +323,36 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -549,8 +360,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -572,8 +382,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -581,8 +390,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -593,104 +401,39 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -698,8 +441,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -721,8 +463,7 @@ public void AppendFormat(string format, T1 arg1, T2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -730,8 +471,7 @@ public void AppendFormat(string format, T1 arg1, T2 else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -742,117 +482,42 @@ public void AppendFormat(string format, T1 arg1, T2 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -860,8 +525,7 @@ public void AppendFormat(string format, T1 arg1, T2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -883,8 +547,7 @@ public void AppendFormat(string format, T1 arg1, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -892,8 +555,7 @@ public void AppendFormat(string format, T1 arg1, else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -904,130 +566,45 @@ public void AppendFormat(string format, T1 arg1, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1035,8 +612,7 @@ public void AppendFormat(string format, T1 arg1, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1058,8 +634,7 @@ public void AppendFormat(string format, T1 a if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1067,8 +642,7 @@ public void AppendFormat(string format, T1 a else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1079,143 +653,48 @@ public void AppendFormat(string format, T1 a switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1223,8 +702,7 @@ public void AppendFormat(string format, T1 a var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1246,8 +724,7 @@ public void AppendFormat(string format, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1255,8 +732,7 @@ public void AppendFormat(string format, else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1267,156 +743,51 @@ public void AppendFormat(string format, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1424,8 +795,7 @@ public void AppendFormat(string format, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1447,8 +817,7 @@ public void AppendFormat(string fo if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1456,8 +825,7 @@ public void AppendFormat(string fo else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1468,169 +836,54 @@ public void AppendFormat(string fo switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1638,8 +891,7 @@ public void AppendFormat(string fo var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1661,8 +913,7 @@ public void AppendFormat(stri if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1670,8 +921,7 @@ public void AppendFormat(stri else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1682,182 +932,57 @@ public void AppendFormat(stri switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1865,8 +990,7 @@ public void AppendFormat(stri var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1888,8 +1012,7 @@ public void AppendFormat if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1897,8 +1020,7 @@ public void AppendFormat else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1909,195 +1031,60 @@ public void AppendFormat switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -2105,8 +1092,7 @@ public void AppendFormat var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2128,8 +1114,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, writeFormat, nameof(arg14)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -2358,8 +1197,7 @@ public void AppendFormat 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2381,8 +1219,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, writeFormat, nameof(arg14)); + continue; case 14: - { - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg15, writeFormat, nameof(arg15)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -2624,8 +1305,7 @@ public void AppendFormat 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2647,8 +1327,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, writeFormat, nameof(arg14)); + continue; case 14: - { - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg15, writeFormat, nameof(arg15)); + continue; case 15: - { - if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg16)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg16, writeFormat, nameof(arg16)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -2903,8 +1416,7 @@ public void AppendFormat 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index f6faf9e3..5acbf83a 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -366,6 +366,20 @@ static void ThrowNestedException() throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); } + private void AppendFormatInternal(T arg, StandardFormat writeFormat, string argName) + { + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(argName); + } + } + index += written; + } + + /// /// Register custom formatter /// diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 634c583b..515186d2 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -21,9 +21,7 @@ public void AppendFormat(string format, T1 arg1) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -31,9 +29,7 @@ public void AppendFormat(string format, T1 arg1) else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -43,41 +39,24 @@ public void AppendFormat(string format, T1 arg1) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -85,9 +64,7 @@ public void AppendFormat(string format, T1 arg1) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -109,9 +86,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -119,9 +94,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -131,54 +104,27 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -186,9 +132,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -210,9 +154,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -220,9 +162,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -232,67 +172,30 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -300,9 +203,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -324,9 +225,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -334,9 +233,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -346,80 +243,33 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -427,9 +277,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -451,9 +299,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -461,9 +307,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -473,93 +317,36 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -567,9 +354,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -591,9 +376,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -601,9 +384,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -613,106 +394,39 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -720,9 +434,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -744,9 +456,7 @@ public void AppendFormat(string format, T1 arg1, T2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -754,9 +464,7 @@ public void AppendFormat(string format, T1 arg1, T2 else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -766,119 +474,42 @@ public void AppendFormat(string format, T1 arg1, T2 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -886,9 +517,7 @@ public void AppendFormat(string format, T1 arg1, T2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -910,9 +539,7 @@ public void AppendFormat(string format, T1 arg1, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -920,9 +547,7 @@ public void AppendFormat(string format, T1 arg1, else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -932,132 +557,45 @@ public void AppendFormat(string format, T1 arg1, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1065,9 +603,7 @@ public void AppendFormat(string format, T1 arg1, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1089,9 +625,7 @@ public void AppendFormat(string format, T1 a if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1099,9 +633,7 @@ public void AppendFormat(string format, T1 a else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1111,145 +643,48 @@ public void AppendFormat(string format, T1 a switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1257,9 +692,7 @@ public void AppendFormat(string format, T1 a var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1281,9 +714,7 @@ public void AppendFormat(string format, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1291,9 +722,7 @@ public void AppendFormat(string format, else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1303,158 +732,51 @@ public void AppendFormat(string format, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1462,9 +784,7 @@ public void AppendFormat(string format, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1486,9 +806,7 @@ public void AppendFormat(string fo if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1496,9 +814,7 @@ public void AppendFormat(string fo else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1508,171 +824,54 @@ public void AppendFormat(string fo switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1680,9 +879,7 @@ public void AppendFormat(string fo var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1704,9 +901,7 @@ public void AppendFormat(stri if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1714,9 +909,7 @@ public void AppendFormat(stri else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1726,184 +919,57 @@ public void AppendFormat(stri switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -1911,9 +977,7 @@ public void AppendFormat(stri var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1935,9 +999,7 @@ public void AppendFormat if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1945,9 +1007,7 @@ public void AppendFormat else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1957,197 +1017,60 @@ public void AppendFormat switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -2155,9 +1078,7 @@ public void AppendFormat var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2179,9 +1100,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, indexParse.FormatString, nameof(arg14)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -2412,9 +1182,7 @@ public void AppendFormat 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2436,9 +1204,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, indexParse.FormatString, nameof(arg14)); + continue; case 14: - { - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg15, indexParse.FormatString, nameof(arg15)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -2682,9 +1289,7 @@ public void AppendFormat 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2706,9 +1311,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, indexParse.FormatString, nameof(arg14)); + continue; case 14: - { - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg15, indexParse.FormatString, nameof(arg15)); + continue; case 15: - { - if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg16)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg16, indexParse.FormatString, nameof(arg16)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -2965,9 +1399,7 @@ public void AppendFormat 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt index ae48c2ee..12b53b5e 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt @@ -29,9 +29,7 @@ namespace Cysharp.Text if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -39,9 +37,7 @@ namespace Cysharp.Text else { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -52,42 +48,25 @@ namespace Cysharp.Text { <# for(var j = 0; j < i; j++) { #> case <#= j #>: - { - if (!FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer.AsSpan(index), out var written, indexParse.FormatString)) - { - Grow(written); - if (!FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer.AsSpan(index), out written, indexParse.FormatString)) - { - ThrowArgumentException(nameof(arg<#= j + 1 #>)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg<#= j + 1 #>, indexParse.FormatString, nameof(arg<#= j + 1 #>)); + continue; <# } #> default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(size); - format.AsSpan(copyFrom, size).CopyTo(buffer.AsSpan(index)); - index += size; + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; continue; } } - - NEXT_LOOP: - continue; } { @@ -95,9 +74,7 @@ namespace Cysharp.Text var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(copyLength); - format.AsSpan(copyFrom, copyLength).CopyTo(buffer.AsSpan(index)); - index += copyLength; + Append(format.AsSpan(copyFrom, copyLength)); } } } diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 96c5fbb6..7a4368a6 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -565,6 +565,19 @@ static void ThrowNestedException() throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); } + void AppendFormatInternal(T arg1, ReadOnlySpan format, string argName) + { + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, format)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(argName); + } + } + index += written; + } + /// /// Register custom formatter /// diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index a592f591..8fd66bc9 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -22,8 +22,7 @@ public void AppendFormat(string format, T1 arg1) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -31,8 +30,7 @@ public void AppendFormat(string format, T1 arg1) else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -43,39 +41,24 @@ public void AppendFormat(string format, T1 arg1) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -83,8 +66,7 @@ public void AppendFormat(string format, T1 arg1) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -106,8 +88,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -115,8 +96,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -127,52 +107,27 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -180,8 +135,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -203,8 +157,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -212,8 +165,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -224,65 +176,30 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -290,8 +207,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -313,8 +229,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -322,8 +237,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -334,78 +248,33 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -413,8 +282,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -436,8 +304,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -445,8 +312,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -457,91 +323,36 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -549,8 +360,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -572,8 +382,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -581,8 +390,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -593,104 +401,39 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -698,8 +441,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -721,8 +463,7 @@ public void AppendFormat(string format, T1 arg1, T2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -730,8 +471,7 @@ public void AppendFormat(string format, T1 arg1, T2 else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -742,117 +482,42 @@ public void AppendFormat(string format, T1 arg1, T2 switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -860,8 +525,7 @@ public void AppendFormat(string format, T1 arg1, T2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -883,8 +547,7 @@ public void AppendFormat(string format, T1 arg1, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -892,8 +555,7 @@ public void AppendFormat(string format, T1 arg1, else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -904,130 +566,45 @@ public void AppendFormat(string format, T1 arg1, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1035,8 +612,7 @@ public void AppendFormat(string format, T1 arg1, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1058,8 +634,7 @@ public void AppendFormat(string format, T1 a if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1067,8 +642,7 @@ public void AppendFormat(string format, T1 a else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1079,143 +653,48 @@ public void AppendFormat(string format, T1 a switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1223,8 +702,7 @@ public void AppendFormat(string format, T1 a var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1246,8 +724,7 @@ public void AppendFormat(string format, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1255,8 +732,7 @@ public void AppendFormat(string format, else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1267,156 +743,51 @@ public void AppendFormat(string format, switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1424,8 +795,7 @@ public void AppendFormat(string format, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1447,8 +817,7 @@ public void AppendFormat(string fo if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1456,8 +825,7 @@ public void AppendFormat(string fo else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1468,169 +836,54 @@ public void AppendFormat(string fo switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1638,8 +891,7 @@ public void AppendFormat(string fo var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1661,8 +913,7 @@ public void AppendFormat(stri if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1670,8 +921,7 @@ public void AppendFormat(stri else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1682,182 +932,57 @@ public void AppendFormat(stri switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -1865,8 +990,7 @@ public void AppendFormat(stri var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -1888,8 +1012,7 @@ public void AppendFormat if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1897,8 +1020,7 @@ public void AppendFormat else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -1909,195 +1031,60 @@ public void AppendFormat switch (indexParse.Index) { case 0: - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -2105,8 +1092,7 @@ public void AppendFormat var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2128,8 +1114,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, writeFormat, nameof(arg14)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -2358,8 +1197,7 @@ public void AppendFormat 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2381,8 +1219,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, writeFormat, nameof(arg14)); + continue; case 14: - { - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg15, writeFormat, nameof(arg15)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -2624,8 +1305,7 @@ public void AppendFormat 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } @@ -2647,8 +1327,7 @@ public void AppendFormat.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg1)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + continue; case 1: - { - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg2, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg2)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + continue; case 2: - { - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg3, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg3)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + continue; case 3: - { - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg4, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg4)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + continue; case 4: - { - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg5, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg5)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + continue; case 5: - { - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg6, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg6)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + continue; case 6: - { - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg7, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg7)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + continue; case 7: - { - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg8, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg8)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + continue; case 8: - { - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg9, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg9)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + continue; case 9: - { - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg10, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg10)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + continue; case 10: - { - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg11, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg11)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + continue; case 11: - { - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg12, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg12)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + continue; case 12: - { - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg13, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg13)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + continue; case 13: - { - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg14, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg14)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg14, writeFormat, nameof(arg14)); + continue; case 14: - { - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg15, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg15)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg15, writeFormat, nameof(arg15)); + continue; case 15: - { - if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg16, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg16)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg16, writeFormat, nameof(arg16)); + continue; default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -2903,8 +1416,7 @@ public void AppendFormat 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt index c556378d..244d9f64 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.tt @@ -30,8 +30,7 @@ namespace Cysharp.Text if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -39,8 +38,7 @@ namespace Cysharp.Text else { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); } // try to find range @@ -52,40 +50,25 @@ namespace Cysharp.Text { <# for(var j = 0; j < i; j++) { #> case <#= j #>: - { - if (!FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer.AsSpan(index), out var written, writeFormat)) - { - Grow(written); - if (!FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer.AsSpan(index), out written, writeFormat)) - { - ThrowArgumentException(nameof(arg<#= j + 1 #>)); - } - } - index += written; - goto NEXT_LOOP; - } + AppendFormatInternal(arg<#= j + 1 #>, writeFormat, nameof(arg<#= j + 1 #>)); + continue; <# } #> default: ThrowFormatException(); break; } - - ThrowFormatException(); } else if (format[i] == '}') { if (i != format.Length && format[i + 1] == '}') { var size = i - copyFrom; - TryGrow(UTF8NoBom.GetMaxByteCount(size)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, size), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; } } - NEXT_LOOP: - continue; } { @@ -93,8 +76,7 @@ namespace Cysharp.Text var copyLength = format.Length - copyFrom; if (copyLength > 0) { - TryGrow(UTF8NoBom.GetMaxByteCount(copyLength)); - index += UTF8NoBom.GetBytes(format.AsSpan(copyFrom, copyLength), buffer.AsSpan(index)); + Append(format.AsSpan(copyFrom, copyLength)); } } } diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index f6faf9e3..5acbf83a 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -366,6 +366,20 @@ static void ThrowNestedException() throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); } + private void AppendFormatInternal(T arg, StandardFormat writeFormat, string argName) + { + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var written, writeFormat)) + { + Grow(written); + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out written, writeFormat)) + { + ThrowArgumentException(argName); + } + } + index += written; + } + + /// /// Register custom formatter /// From 111a5d5279ffe624326468358e2041a7a0497713 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Aug 2020 16:29:31 +0900 Subject: [PATCH 078/139] add unity meta --- .../NestedStringBuilderCreationException.cs.meta | 11 +++++++++++ src/ZString.Unity/ProjectSettings/ProjectVersion.txt | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs.meta diff --git a/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs.meta new file mode 100644 index 00000000..0e5262e5 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c2e6121a89e941e4d8388e6842ad3551 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/ProjectSettings/ProjectVersion.txt b/src/ZString.Unity/ProjectSettings/ProjectVersion.txt index 83a18014..291a7485 100644 --- a/src/ZString.Unity/ProjectSettings/ProjectVersion.txt +++ b/src/ZString.Unity/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2019.3.0a2 -m_EditorVersionWithRevision: 2019.3.0a2 (fa7740529556) +m_EditorVersion: 2019.4.5f1 +m_EditorVersionWithRevision: 2019.4.5f1 (81610f64359c) From 80f2211e2e30ea0ccf155d86976eee22ddef1b4c Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Aug 2020 16:29:46 +0900 Subject: [PATCH 079/139] update license readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c147ae2..65a72ab4 100644 --- a/README.md +++ b/README.md @@ -297,4 +297,4 @@ License --- This library is licensed under the the MIT License. -.NET Standard 2.0 and Unity version borrows [dotnet/runtime](https://github.com/dotnet/runtime) conversion methods, there exists under `ZString/Number` directory. +.NET Standard 2.0 and Unity version borrows [dotnet/runtime](https://github.com/dotnet/runtime) conversion methods, there exists under `ZString/Number` directory. This third-party license follows [runtime/LICENSE.TXT](https://github.com/dotnet/runtime/blob/master/LICENSE.TXT). \ No newline at end of file From 1691c24d4098378770bedefcc54804b9160b6db5 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Aug 2020 16:29:50 +0900 Subject: [PATCH 080/139] ignore --- .gitignore | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.gitignore b/.gitignore index abc89380..a84f2f0d 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,33 @@ src/ZString.Unity/ZString.csproj src/ZString.Unity/ZString.Unity.sln src/ZString.Unity/ZString.Unity.unitypackage + +src/ZString.Unity/Unity.Analytics.DataPrivacy.csproj + +src/ZString.Unity/Unity.CollabProxy.Editor.csproj + +src/ZString.Unity/Unity.Rider.Editor.csproj + +src/ZString.Unity/Unity.TextMeshPro.csproj + +src/ZString.Unity/Unity.TextMeshPro.Editor.csproj + +src/ZString.Unity/Unity.Timeline.csproj + +src/ZString.Unity/Unity.Timeline.Editor.csproj + +src/ZString.Unity/Unity.VisualStudio.Editor.csproj + +src/ZString.Unity/Unity.VSCode.Editor.csproj + +src/ZString.Unity/UnityEditor.TestRunner.csproj + +src/ZString.Unity/UnityEditor.UI.csproj + +src/ZString.Unity/UnityEngine.Advertisements.csproj + +src/ZString.Unity/UnityEngine.Monetization.csproj + +src/ZString.Unity/UnityEngine.TestRunner.csproj + +src/ZString.Unity/UnityEngine.UI.csproj From 450d01f978fc3b56fa54b9c343661bfc95a6bc50 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Aug 2020 16:39:11 +0900 Subject: [PATCH 081/139] more unity meta --- .../Scripts/ZString/ReadOnlyListAdaptor.cs.meta | 11 +++++++++++ .../Scripts/ZString/StringBuilder.AppendJoin.cs.meta | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ReadOnlyListAdaptor.cs.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/StringBuilder.AppendJoin.cs.meta diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ReadOnlyListAdaptor.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/ReadOnlyListAdaptor.cs.meta new file mode 100644 index 00000000..e7027a48 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ReadOnlyListAdaptor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6bac71655584ae549bb144276ee22eed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/StringBuilder.AppendJoin.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/StringBuilder.AppendJoin.cs.meta new file mode 100644 index 00000000..2f2bcc14 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/StringBuilder.AppendJoin.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9e8eda83a35921f4ca67df72e7e5f3e9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 808372725e20e90fe1d6cc5368c7a20ecabc6b33 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Aug 2020 17:00:06 +0900 Subject: [PATCH 082/139] GitHub Actions --- .circleci/config.yml | 131 ---------------------------- .github/workflows/build-debug.yml | 67 ++++++++++++++ .github/workflows/build-release.yml | 105 ++++++++++++++++++++++ .github/workflows/stale.yml | 24 +++++ .github/workflows/toc.yml | 15 ++++ README.md | 7 +- 6 files changed, 217 insertions(+), 132 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workflows/build-debug.yml create mode 100644 .github/workflows/build-release.yml create mode 100644 .github/workflows/stale.yml create mode 100644 .github/workflows/toc.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 1f514747..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,131 +0,0 @@ -version: 2.1 -executors: - dotnet: - docker: - - image: mcr.microsoft.com/dotnet/core/sdk:3.1 - environment: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - NUGET_XMLDOC_MODE: skip - dotnet2: - docker: - - image: mcr.microsoft.com/dotnet/core/sdk:2.1 - environment: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - NUGET_XMLDOC_MODE: skip - unity: - # https://hub.docker.com/r/gableroux/unity3d/tags - parameters: - version: {type: string} - docker: - - image: gableroux/unity3d:<< parameters.version >> - go: - docker: - - image: circleci/golang -commands: - unity_activate: - parameters: - unity_version: {type: string} - unity_license: {type: string} - steps: - # get activation file, if fail to activate unity, use this key and activate from https://license.unity3d.com/manual - - run: apt update && apt install libunwind8 -y - - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -logFile -createManualActivationFile || exit 0 - - store_artifacts: - path: Unity_v<< parameters.unity_version >>.alf - destination: /Unity_v<< parameters.unity_version >>.alf - # get from UNITY_LICENSE envvar(base64 encoded(cat foo.ulf | base64 )), this file is generated from above manual activation - - run: echo << parameters.unity_license >> | base64 -di >> .circleci/Unity.ulf - - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .circleci/Unity.ulf || exit 0 -jobs: - # create package for Unity - build-unity: - parameters: - unity_version: {type: string} - unity_license: {type: string} - executor: - name: unity - version: << parameters.unity_version >> - steps: - - run: apt update && apt install git -y - - checkout - - unity_activate: - unity_version: << parameters.unity_version >> - unity_license: << parameters.unity_license >> - - run: - name: Export unitypackage - command: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export - working_directory: src/ZString.Unity - - persist_to_workspace: - root: ./src/ZString.Unity/ - paths: - - ./ZString.Unity.unitypackage - build-test: - executor: dotnet - steps: - - checkout - - run: dotnet build src/ZString -c Debug - - run: dotnet test tests/ZString.Tests -c Debug < /dev/null -# test-netcore2: -# executor: dotnet2 -# steps: -# - checkout -# - run: dotnet test tests/ZString.NetCore2Tests -c Debug < /dev/null - build-push: - executor: dotnet - steps: - - checkout - - run: dotnet build src/ZString -c Release -p:Version=${CIRCLE_TAG} - - run: dotnet build tests/ZString.Tests -c Release -p:Version=${CIRCLE_TAG} - - run: dotnet test tests/ZString.Tests -c Release --no-build < /dev/null - - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${CIRCLE_TAG} - - store_artifacts: - path: src/ZString/bin/Release/ - destination: /ZString/ - - run: dotnet nuget push ./src/ZString/bin/Release/ZString.${CIRCLE_TAG}.nupkg -s https://www.nuget.org/api/v2/package -k ${NUGET_KEY} - # upload to github by ghr - upload-github: - executor: go - steps: - - attach_workspace: - at: . - - run: go get github.com/tcnksm/ghr - - run: ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} ${CIRCLE_TAG} . - - store_artifacts: - path: ZString.Unity.unitypackage - destination: ZString.Unity.unitypackage -workflows: - version: 2 - default-pipeline: - jobs: - - build-test: - filters: - tags: - only: /.*/ -# - test-netcore2: -# filters: -# tags: -# only: /.*/ - - build-unity: - unity_version: 2019.1.2f1 - unity_license: ${UNITY_LICENSE_2019_1} - filters: - tags: - only: /^\d\.\d\.\d.*/ - branches: - ignore: /.*/ - - build-push: - filters: - tags: - only: /^\d\.\d\.\d.*/ - branches: - ignore: /.*/ - context: cysharp-nuget - - upload-github: - requires: - - build-unity - - build-push - filters: - tags: - only: /^\d\.\d\.\d.*/ - branches: - ignore: /.*/ \ No newline at end of file diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml new file mode 100644 index 00000000..b9c37f5f --- /dev/null +++ b/.github/workflows/build-debug.yml @@ -0,0 +1,67 @@ +name: Build-Debug + +on: + push: + branches: + - "**" + tags: + - "!*" # not a tag push + pull_request: + types: + - opened + - synchronize + +jobs: + build-dotnet: + runs-on: ubuntu-latest + env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + NUGET_XMLDOC_MODE: skip + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.101 + - run: dotnet build src/ZString -c Debug + - run: dotnet test tests/ZString.Tests -c Debug < /dev/null + + build-unity: + strategy: + matrix: + unity: ['2019.3.9f1', '2020.1.0b5'] + include: + - unity: 2019.3.9f1 + license: UNITY_2019_3 + - unity: 2020.1.0b5 + license: UNITY_2020_1 + runs-on: ubuntu-latest + container: + # with linux-il2cpp. image from https://hub.docker.com/r/gableroux/unity3d/tags + image: gableroux/unity3d:${{ matrix.unity }}-linux-il2cpp + steps: + - run: apt update && apt install git -y + - uses: actions/checkout@v2 + # create unity activation file and store to artifacts. + - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -logFile -createManualActivationFile || exit 0 + - uses: actions/upload-artifact@v1 + with: + name: Unity_v${{ matrix.unity }}.alf + path: ./Unity_v${{ matrix.unity }}.alf + # activate Unity from manual license file(ulf) + - run: echo -n "$UNITY_LICENSE" >> .Unity.ulf + env: + UNITY_LICENSE: ${{ secrets[matrix.license] }} + - name: Activate Unity, always returns a success. But if a subsequent run fails, the activation may have failed(if succeeded, shows `Next license update check is after` and not shows other message(like GUID != GUID). If fails not). In that case, upload the artifact's .alf file to https://license.unity3d.com/manual to get the .ulf file and set it to secrets. + run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .Unity.ulf || exit 0 + + # Execute scripts: Export Package + - name: Export unitypackage + run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export + working-directory: src/ZString.Unity + + # Store artifacts. + - uses: actions/upload-artifact@v1 + with: + name: ZString.Unity.unitypackage + path: ./src/ZString.Unity/ZString.Unity.unitypackage \ No newline at end of file diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 00000000..a6bbd36a --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,105 @@ +name: Build-Release + +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+*" + +jobs: + build-dotnet: + runs-on: ubuntu-latest + env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + NUGET_XMLDOC_MODE: skip + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.101 + # set release tag(*.*.*) to env.GIT_TAG + - run: echo ::set-env name=GIT_TAG::${GITHUB_REF#refs/tags/} + - run: dotnet build src/ZString -c Release -p:Version=${{ env.GIT_TAG }} + - run: dotnet test tests/ZString.Tests -c Release --no-build + - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} + + # Store artifacts. + - uses: actions/upload-artifact@v1 + with: + name: nuget + path: ./src/ZString/bin/Release/ZString.${{ env.GIT_TAG }}.nupkg + + build-unity: + strategy: + matrix: + unity: ['2019.3.9f1'] + include: + - unity: 2019.3.9f1 + license: UNITY_2019_3 + runs-on: ubuntu-latest + container: + # with linux-il2cpp. image from https://hub.docker.com/r/gableroux/unity3d/tags + image: gableroux/unity3d:${{ matrix.unity }}-linux-il2cpp + steps: + - run: apt update && apt install git -y + - uses: actions/checkout@v2 + - run: echo -n "$UNITY_LICENSE" >> .Unity.ulf + env: + UNITY_LICENSE: ${{ secrets[matrix.license] }} + - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .Unity.ulf || exit 0 + + # set release tag(*.*.*) to env.GIT_TAG + - run: echo ::set-env name=GIT_TAG::${GITHUB_REF#refs/tags/} + + # Execute scripts: Export Package + - name: Export unitypackage + run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export + working-directory: src/ZString.Unity + env: + UNITY_PACKAGE_VERSION: ${{ env.GIT_TAG }} + + # Store artifacts. + - uses: actions/upload-artifact@v1 + with: + name: ZString.Unity.${{ env.GIT_TAG }}.unitypackage + path: ./src/ZString.Unity/ZString.Unity.${{ env.GIT_TAG }}.unitypackage + + create-release: + needs: [build-dotnet, build-unity] + runs-on: ubuntu-latest + env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + NUGET_XMLDOC_MODE: skip + steps: + # setup dotnet for nuget push + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.101 + # set release tag(*.*.*) to env.GIT_TAG + - run: echo ::set-env name=GIT_TAG::${GITHUB_REF#refs/tags/} + + # Create Releases + - uses: actions/create-release@v1 + id: create_release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Ver.${{ github.ref }} + + # Download (All) Artifacts to current directory + - uses: actions/download-artifact@v2-preview + + # Upload to NuGet + - run: dotnet nuget push "./nuget/*.nupkg" -s https://www.nuget.org/api/v2/package -k ${{ secrets.NUGET_KEY }} + + # Upload to Releases(unitypackage) + - uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./ZString.Unity.${{ env.GIT_TAG }}.unitypackage/ZString.Unity.${{ env.GIT_TAG }}.unitypackage + asset_name: ZString.Unity.${{ env.GIT_TAG }}.unitypackage + asset_content_type: application/octet-stream \ No newline at end of file diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..70c3a281 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,24 @@ +name: "Close stale issues" + +on: + schedule: + - cron: "0 0 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + # enable issue + stale-issue-message: "This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 7 days." + stale-issue-label: "stale" + # enable pr + stale-pr-message: "This PR is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 7 days." + stale-pr-label: "stale" + days-before-stale: 90 + days-before-close: 7 + exempt-issue-labels: "wip" + exempt-pr-labels: "wip" + remove-stale-when-updated: true diff --git a/.github/workflows/toc.yml b/.github/workflows/toc.yml new file mode 100644 index 00000000..f7519c3d --- /dev/null +++ b/.github/workflows/toc.yml @@ -0,0 +1,15 @@ +name: TOC Generator + +on: + push: + paths: + - 'README.md' + +jobs: + generateTOC: + name: TOC Generator + runs-on: ubuntu-latest + steps: + - uses: technote-space/toc-generator@v2.4.0 + with: + TOC_TITLE: "## Table of Contents" \ No newline at end of file diff --git a/README.md b/README.md index 61b40c4c..dd8a4afa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ZString === -[![CircleCI](https://circleci.com/gh/Cysharp/ZString.svg?style=svg)](https://circleci.com/gh/Cysharp/ZString) +[![GitHub Actions](https://github.com/Cysharp/ZString/workflows/Build-Debug/badge.svg)](https://github.com/Cysharp/ZString/actions) [![Releases](https://img.shields.io/github/release/Cysharp/ZString.svg)](https://github.com/Cysharp/ZString/releases) **Z**ero Allocation **String**Builder for .NET Core and Unity. @@ -33,6 +33,11 @@ The blog post of detailed explanation by author: [medium@neuecc/ZString](https:/ Related project for loggin using with ZString, [Cysharp/ZLogger](https://github.com/Cysharp/ZLogger) - Zero Allocation Text/Strcutured Logger. + + +## Table of Contents + + Getting Started --- For .NET Core, use NuGet. From 17e8ddc236e76198b9abc0e3b576ae71cc2ab426 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Aug 2020 08:01:08 +0000 Subject: [PATCH 083/139] docs: update TOC --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index dd8a4afa..51bf51c8 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,13 @@ Related project for loggin using with ZString, [Cysharp/ZLogger](https://github. ## Table of Contents + +- [Getting Started](#getting-started) +- [Reference](#reference) +- [Unity](#unity) +- [Advanced Tips](#advanced-tips) +- [License](#license) + Getting Started From 7890fa1b5970510575a6682e930f111f9ecb65bd Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Aug 2020 17:37:00 +0900 Subject: [PATCH 084/139] Add package.json --- src/ZString.Unity/Assets/Scripts/ZString/package.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/package.json diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json b/src/ZString.Unity/Assets/Scripts/ZString/package.json new file mode 100644 index 00000000..d2c495b5 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json @@ -0,0 +1,11 @@ +{ + "name": "com.cysharp.zstring", + "displayName": "ZString", + "version": "2.2.0", + "unity": "2018.4", + "description": "Zero Allocation StringBuilder for .NET Core and Unity.", + "keywords": [ "String", "Performance" ], + "license": "MIT", + "category": "Scripting", + "dependencies": {} +} \ No newline at end of file From 14c36f5bafc673cdcca0a6c8dc38c8733571c161 Mon Sep 17 00:00:00 2001 From: neuecc Date: Mon, 3 Aug 2020 17:37:50 +0900 Subject: [PATCH 085/139] meta --- src/ZString.Unity/Assets/Scripts/ZString/package.json.meta | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/package.json.meta diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json.meta b/src/ZString.Unity/Assets/Scripts/ZString/package.json.meta new file mode 100644 index 00000000..494bc715 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ba0803434cb80a14083de2d39cc00351 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 13c0b18f299fca92be74f893389e76f3685f2f05 Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Tue, 4 Aug 2020 13:22:23 +0900 Subject: [PATCH 086/139] chore: remove generate unity alf (activation license file) --- .github/workflows/build-debug.yml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index b9c37f5f..c3e329da 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -29,7 +29,7 @@ jobs: build-unity: strategy: matrix: - unity: ['2019.3.9f1', '2020.1.0b5'] + unity: ["2019.3.9f1", "2020.1.0b5"] include: - unity: 2019.3.9f1 license: UNITY_2019_3 @@ -42,13 +42,6 @@ jobs: steps: - run: apt update && apt install git -y - uses: actions/checkout@v2 - # create unity activation file and store to artifacts. - - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -logFile -createManualActivationFile || exit 0 - - uses: actions/upload-artifact@v1 - with: - name: Unity_v${{ matrix.unity }}.alf - path: ./Unity_v${{ matrix.unity }}.alf - # activate Unity from manual license file(ulf) - run: echo -n "$UNITY_LICENSE" >> .Unity.ulf env: UNITY_LICENSE: ${{ secrets[matrix.license] }} @@ -60,8 +53,8 @@ jobs: run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export working-directory: src/ZString.Unity - # Store artifacts. + # Store artifacts. - uses: actions/upload-artifact@v1 with: name: ZString.Unity.unitypackage - path: ./src/ZString.Unity/ZString.Unity.unitypackage \ No newline at end of file + path: ./src/ZString.Unity/ZString.Unity.unitypackage From 22dd0382f926f203654444d9c5d60c84d785e9db Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Tue, 4 Aug 2020 13:40:32 +0900 Subject: [PATCH 087/139] chore: Unity Package version on debug build --- .github/workflows/build-debug.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index c3e329da..236a6ced 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -54,7 +54,7 @@ jobs: working-directory: src/ZString.Unity # Store artifacts. - - uses: actions/upload-artifact@v1 + - uses: actions/upload-artifact@v2 with: - name: ZString.Unity.unitypackage - path: ./src/ZString.Unity/ZString.Unity.unitypackage + name: ZString.Unity.unitypackage.zip + path: ./src/ZString.Unity/*.unitypackage From 85703105778fba9c41db19c03e5627f554888b4f Mon Sep 17 00:00:00 2001 From: udaken Date: Mon, 20 Jul 2020 00:43:23 +0900 Subject: [PATCH 088/139] add BCL-Compatibility tests --- tests/ZString.Tests/CompositeFormatTest.cs | 127 +++++++++++++++++++++ tests/ZString.Tests/FormatTest.cs | 66 ++++++++++- 2 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 tests/ZString.Tests/CompositeFormatTest.cs diff --git a/tests/ZString.Tests/CompositeFormatTest.cs b/tests/ZString.Tests/CompositeFormatTest.cs new file mode 100644 index 00000000..bf0614e8 --- /dev/null +++ b/tests/ZString.Tests/CompositeFormatTest.cs @@ -0,0 +1,127 @@ +using Cysharp.Text; +using FluentAssertions; +using System; +using System.Buffers; +using System.Text; +using Xunit; +using static FluentAssertions.FluentActions; + +using static ZStringTests.FormatTest; +namespace ZStringTests +{ + public class CompositeFormatTest + { + [Theory] + [InlineData("{1}")] + [InlineData("{-0}")] + [InlineData("{-1}")] + [InlineData("}")] + [InlineData("{")] + [InlineData("{}")] + [InlineData("{A}")] + [InlineData("{1A}")] + [InlineData("{0x0}")] + [InlineData("{\uff11}")] // Full-Width One + [InlineData("{ }")] + [InlineData("{ 1}")] + [InlineData("{0 0}")] + [InlineData("{0+0}")] + [InlineData("{0")] + [InlineData("{foo")] + [InlineData("{{0}")] + [InlineData("{{{0")] + [InlineData("0}")] + [InlineData("bar}")] + [InlineData("{0}}")] + [InlineData("0}}}")] + [InlineData("{:0}")] + [InlineData("{0{}")] + [InlineData("{0{1}}")] + [InlineData("{,0}")] + [InlineData("{ 0,0}")] + [InlineData("{,-0}")] + [InlineData("{0,-}")] + [InlineData("{0,- 0}")] + [InlineData("{0,--0}")] + [InlineData("{:}")] + [InlineData("{,:}")] + [InlineData(" { , : } ")] + [InlineData("{:,}")] + [InlineData("{::}")] + [InlineData("{,,}")] + [InlineData(@"{\0}")] + [InlineData(@"{0\,0}")] + [InlineData(@"{0,0\:}")] + [InlineData(@"{0:\}}")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "<ۗ>")] + public void IncorrectFormat(string format) + { + var value = 9999; + var expected = CatchException(() => string.Format(format, value)); + var actual = CatchException(() => ZString.Format(format, value)); + + expected.Should().NotBeNull(); // test miss! + actual.Should().BeOfType(expected.GetType()); + + Exception CatchException(Func func) + { + try + { + _ = func(); + return null; + } + catch (Exception e) + { + return e; + } + } + } + + [Fact] + public void AlignmentComponentInt() + { + Test("{1,-1}{0,1}", Int64.MinValue, Int64.MaxValue); + Test("{0,1}{1,-1}", 1, 1); + Test("{0,10}{1,-10}", 1, 1); + } + [Fact] + public void AlignmentComponentString() + { + Test("{1,0}{0,0}", "right", "left"); + Test("{0,3}{1,-3}", "Foo", "Foo"); + Test("{0,4}{1,-4}", "Foo", "Foo"); + } + [Fact] + public void AlignmentComponent() + { + Test("{1,-" + 1000 + "}{0," + 1000 + "}", + "", Int64.MaxValue); + var guid = Guid.NewGuid(); + Test(testUtf8: false, "{0,10:X}{{0}}{1,-10:c}", Guid.NewGuid(), DateTime.Now.TimeOfDay.Negate()); + + string[] names = { "Adam", "Bridgette", "Carla", "Daniel", "Ebenezer", "Francine", "George" }; + decimal[] hours = { 40, 6.667m, 40.39m, 82, 40.333m, 80, 16.75m }; + + for (int ctr = 0; ctr < names.Length; ctr++) + Test("{0,-20} {1,5:F}", names[ctr], hours[ctr]); + } + + + [Fact] + public void Spaces() + { + var format = "Prime numbers less than 10: {00 , 01 }, {01 ,02 }, {2 ,3 :D }, {3 ,4: X }"; + var expected = string.Format(format, 2, 3, 5, 7); + var actual = ZString.Format(format, 2, 3, 5, 7); + actual.Should().Be(expected); + + } + + [Fact] + public void CompsiteFormats() + { + Test("{{Name = {0}, {1:f}({1:E})}}", "Fred", 500_0000_0000_0000m); + } + + } +} \ No newline at end of file diff --git a/tests/ZString.Tests/FormatTest.cs b/tests/ZString.Tests/FormatTest.cs index 8223b82c..c7fcdb59 100644 --- a/tests/ZString.Tests/FormatTest.cs +++ b/tests/ZString.Tests/FormatTest.cs @@ -10,13 +10,19 @@ namespace ZStringTests { public class FormatTest { - void Test(string format, T0 t0, T1 t1) + internal static void Test(string format, T0 t0, T1 t1) + { + Test(true, format, t0, t1); + } + + internal static void Test(bool testUtf8, string format, T0 t0, T1 t1) { { var actual = ZString.Format(format, t0, t1); var expected = string.Format(format, t0, t1); actual.Should().Be(expected); } + if (testUtf8) { var sb = ZString.CreateUtf8StringBuilder(); sb.AppendFormat(format, t0, t1); @@ -31,6 +37,7 @@ void Test(string format, T0 t0, T1 t1) var expected = string.Format(format, t0, t1); actual.Should().Be(expected); } + if (testUtf8) { var sb = ZString.PrepareUtf8(format); var actual = sb.Format(t0, t1); @@ -39,6 +46,7 @@ void Test(string format, T0 t0, T1 t1) } // Direct + if (testUtf8) { #if NETCOREAPP3_1 var writer = new ArrayBufferWriter(); @@ -50,6 +58,46 @@ void Test(string format, T0 t0, T1 t1) } } + void Test(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) + { + { + var actual = ZString.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + var expected = string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + actual.Should().Be(expected); + } + { + var sb = ZString.CreateUtf8StringBuilder(); + sb.AppendFormat(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + var actual = sb.ToString(); + var expected = string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + actual.Should().Be(expected); + } + + // Prepare + { + var actual = ZString.PrepareUtf16(format).Format(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + var expected = string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + actual.Should().Be(expected); + } + { + var sb = ZString.PrepareUtf8(format); + var actual = sb.Format(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + var expected = string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + actual.Should().Be(expected); + } + + // Direct + { +#if NETCOREAPP3_1 + var writer = new ArrayBufferWriter(); + ZString.Utf8Format(writer, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + var actual = Encoding.UTF8.GetString(writer.WrittenSpan); + var expected = string.Format(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + actual.Should().Be(expected); +#endif + } + } + [Fact] public void EmptyFormat() { @@ -86,6 +134,21 @@ public void DoubleFormat3() Test("abc{0}def{1}ghi", 100, 200); } + [Fact] + public void EmptyFormatString() + { + // UtfFormatter Deny space only + Test(false, "{0:}{1: }", 100, 200); + } + + [Fact] + public void MaximumFormat() + { + Test("abc{0}de{1}f{2}g{3}h{4}i{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}z", + 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600); + } + + [Fact] public void Nullable() { @@ -99,6 +162,7 @@ public void Nullable() public void Comment() { Test("abc{{0}}def{1}ghi", 100, 200); + Test("}}{{{0}{{}}{1}{{", 123, 456); } [Fact] From 2d0f9cfa4162a9558e4d9e6842be6a4c8c6b7803 Mon Sep 17 00:00:00 2001 From: udaken Date: Thu, 6 Aug 2020 19:47:28 +0900 Subject: [PATCH 089/139] Update Benchmark code --- sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs | 10 +++++++++- .../Benchmarks/SixObjectConcatBenchmark.cs | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs b/sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs index adf2ff4f..cab1dad6 100644 --- a/sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs +++ b/sandbox/PerfBenchmark/Benchmarks/FormatBenchmark.cs @@ -14,6 +14,7 @@ public class FormatBenchmark int y; string format; StringBuilder stringBuilder; + Utf16PreparedFormat preparedFormat; public FormatBenchmark() { @@ -21,9 +22,10 @@ public FormatBenchmark() y = int.Parse("200"); format = "x:{0}, y:{1}"; stringBuilder = new StringBuilder(); + preparedFormat = new Utf16PreparedFormat(format); } - [Benchmark] + [Benchmark(Baseline = true)] public string StringFormat() { return string.Format(format, x, y); @@ -35,6 +37,12 @@ public string ZStringFormat() return ZString.Format(format, x, y); } + [Benchmark] + public string ZStringPreparedFormat() + { + return preparedFormat.Format(x, y); + } + [Benchmark] public string StringFormatterFormat() { diff --git a/sandbox/PerfBenchmark/Benchmarks/SixObjectConcatBenchmark.cs b/sandbox/PerfBenchmark/Benchmarks/SixObjectConcatBenchmark.cs index 267ada62..b397bdd9 100644 --- a/sandbox/PerfBenchmark/Benchmarks/SixObjectConcatBenchmark.cs +++ b/sandbox/PerfBenchmark/Benchmarks/SixObjectConcatBenchmark.cs @@ -19,7 +19,7 @@ public SixObjectConcatBenchmark() z = int.Parse("555"); } - [Benchmark] + [Benchmark(Baseline = true)] public string StringPlus() { return "x:" + x + " y:" + y + " z:" + z; From 12f3e69bb85d25345a259a550c0c8d7403509c94 Mon Sep 17 00:00:00 2001 From: udaken Date: Thu, 6 Aug 2020 17:35:27 +0900 Subject: [PATCH 090/139] update BenchmarkVsReleasedVersion --- .../BenchmarkVsReleasedVersion.csproj | 2 +- .../BuiltinTypesBenchmark.cs | 20 +++++++++++++++---- .../FormatBenchmark.cs | 20 +++++++++++++++---- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/sandbox/BenchmarkVsReleasedVersion/BenchmarkVsReleasedVersion.csproj b/sandbox/BenchmarkVsReleasedVersion/BenchmarkVsReleasedVersion.csproj index 7e34c82c..4e032401 100644 --- a/sandbox/BenchmarkVsReleasedVersion/BenchmarkVsReleasedVersion.csproj +++ b/sandbox/BenchmarkVsReleasedVersion/BenchmarkVsReleasedVersion.csproj @@ -9,7 +9,7 @@ - + diff --git a/sandbox/BenchmarkVsReleasedVersion/BuiltinTypesBenchmark.cs b/sandbox/BenchmarkVsReleasedVersion/BuiltinTypesBenchmark.cs index 20b8ab4d..8c223f99 100644 --- a/sandbox/BenchmarkVsReleasedVersion/BuiltinTypesBenchmark.cs +++ b/sandbox/BenchmarkVsReleasedVersion/BuiltinTypesBenchmark.cs @@ -96,18 +96,30 @@ public string FormatN() _byte, _dt, _dto, _decimal, _double, _guid, _short, _float, _ts, _uint, _ulong, _null, _string, _bool, _enum, _char); } - [BenchmarkCategory("CreatePreparedFormat"), Benchmark(Baseline = true)] - public object CreatePreparedFormat_() + [BenchmarkCategory("CreateUtf16PreparedFormat"), Benchmark(Baseline = true)] + public object CreateUtf16PreparedFormat_() { return new PF16(_format); } - [BenchmarkCategory("CreatePreparedFormat"), Benchmark] - public object CreatePreparedFormatN() + [BenchmarkCategory("CreateUtf16PreparedFormat"), Benchmark] + public object CreateUtf16PreparedFormatN() { return new NPF16(_format); } + [BenchmarkCategory("CreateUtf8PreparedFormat"), Benchmark(Baseline = true)] + public object CreateUtf8PreparedFormat_() + { + return new PF8(_format); + } + + [BenchmarkCategory("CreateUtf8PreparedFormat"), Benchmark] + public object CreateUtf8PreparedFormatN() + { + return new NPF8(_format); + } + [BenchmarkCategory("Utf16PreparedFormat"), Benchmark(Baseline = true)] public string Utf16PreparedFormat_() { diff --git a/sandbox/BenchmarkVsReleasedVersion/FormatBenchmark.cs b/sandbox/BenchmarkVsReleasedVersion/FormatBenchmark.cs index 14a49c20..3f6169f0 100644 --- a/sandbox/BenchmarkVsReleasedVersion/FormatBenchmark.cs +++ b/sandbox/BenchmarkVsReleasedVersion/FormatBenchmark.cs @@ -61,18 +61,30 @@ public string FormatN() return NZString.Format(FormatString, x, y); } - [BenchmarkCategory("CreatePreparedFormat"), Benchmark(Baseline = true)] - public object CreatePreparedFormat_() + [BenchmarkCategory("CreateUtf16PreparedFormat"), Benchmark(Baseline = true)] + public object CreateUtf16PreparedFormat_() { return new Utf16PreparedFormat(FormatString); } - [BenchmarkCategory("CreatePreparedFormat"), Benchmark] - public object CreatePreparedFormatN() + [BenchmarkCategory("CreateUtf16PreparedFormat"), Benchmark] + public object CreateUtf16PreparedFormatN() { return new NewZString::Cysharp.Text.Utf16PreparedFormat(FormatString); } + [BenchmarkCategory("CreateUtf8PreparedFormat"), Benchmark(Baseline = true)] + public object CreateUtf8PreparedFormat_() + { + return new Utf8PreparedFormat(FormatString); + } + + [BenchmarkCategory("CreateUtf8PreparedFormat"), Benchmark] + public object CreateUtf8PreparedFormatN() + { + return new NewZString::Cysharp.Text.Utf8PreparedFormat(FormatString); + } + [BenchmarkCategory("Utf16PreparedFormat"), Benchmark(Baseline = true)] public string Utf16PreparedFormat_() { From b2975a8a70c77745edd588763a9292cd994a1dd8 Mon Sep 17 00:00:00 2001 From: udaken Date: Mon, 20 Jul 2020 00:43:44 +0900 Subject: [PATCH 091/139] Improved compatibility of AppendFormat formatting string --- .../Assets/Scripts/ZString/ExceptionUtil.cs | 5 + .../Assets/Scripts/ZString/FormatHelper.cs | 162 + .../Assets/Scripts/ZString/FormatParser.cs | 197 +- .../Assets/Scripts/ZString/PreparedFormat.cs | 6212 +++++------------ .../Scripts/ZString/PreparedFormatHelper.cs | 92 +- .../Utf16ValueStringBuilder.AppendFormat.cs | 640 +- .../ZString/Utf16ValueStringBuilder.cs | 69 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 640 +- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 65 +- .../Scripts/ZString/ZString.Utf8Format.cs | 2672 ++----- .../Assets/Scripts/ZString/ZString.cs | 8 + src/ZString/ExceptionUtil.cs | 5 + src/ZString/FormatHelper.cs | 162 + src/ZString/FormatHelper.tt | 99 + src/ZString/FormatParser.cs | 197 +- src/ZString/PreparedFormat.cs | 6212 +++++------------ src/ZString/PreparedFormat.tt | 53 +- src/ZString/PreparedFormatHelper.cs | 92 +- .../Utf16ValueStringBuilder.AppendFormat.cs | 640 +- .../Utf16ValueStringBuilder.AppendFormat.tt | 25 +- src/ZString/Utf16ValueStringBuilder.cs | 69 +- .../Utf8ValueStringBuilder.AppendFormat.cs | 640 +- .../Utf8ValueStringBuilder.AppendFormat.tt | 25 +- src/ZString/Utf8ValueStringBuilder.cs | 65 +- src/ZString/ZString.Utf8Format.cs | 2672 ++----- src/ZString/ZString.Utf8Format.tt | 122 +- src/ZString/ZString.cs | 8 + src/ZString/ZString.csproj | 9 + 28 files changed, 7474 insertions(+), 14383 deletions(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs create mode 100644 src/ZString/FormatHelper.cs create mode 100644 src/ZString/FormatHelper.tt diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs b/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs index 64413691..401e1c65 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ExceptionUtil.cs @@ -15,5 +15,10 @@ internal static void ThrowFormatException() { throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + + internal static void ThrowFormatError() + { + throw new FormatException("Input string was not in a correct format."); + } } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs b/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs new file mode 100644 index 00000000..5e23b582 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs @@ -0,0 +1,162 @@ +using System; +using System.Text; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + internal static partial class Utf16PreparedFormat + { + public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + where TBufferWriter : IBufferWriter + { + const char sp = (char)' '; + var width = item.Alignment; + var format = item.FormatString.AsSpan(item.Offset, item.Count); + + if (width <= 0) // leftJustify + { + width *= -1; + + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out argWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + sb.Advance(argWritten); + + int padding = width - argWritten; + if (width > 0 && padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + var span = sb.GetSpan(s.Length); + s.AsSpan().CopyTo(span); + sb.Advance(s.Length); + } + else + { + Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc char[s.Length * 2]; + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); + } + } + } + } + internal static partial class Utf8PreparedFormat + { + public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + where TBufferWriter : IBufferWriter + { + const byte sp = (byte)' '; + var width = item.Alignment; + var format = item.StandardFormat; + + if (width <= 0) // leftJustify + { + width *= -1; + + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out argWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + sb.Advance(argWritten); + + int padding = width - argWritten; + if (width > 0 && padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + ZString.AppendChars(ref sb, s.AsSpan()); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); + } + } + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs b/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs index eed62867..a9552815 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/FormatParser.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; namespace Cysharp.Text { @@ -11,45 +12,207 @@ public readonly ref struct ParseResult public readonly int Index; public readonly ReadOnlySpan FormatString; public readonly int LastIndex; + public readonly int Alignment; - public ParseResult(int index, ReadOnlySpan formatString, int lastIndex) + public ParseResult(int index, ReadOnlySpan formatString, int lastIndex, int alignment) { Index = index; FormatString = formatString; LastIndex = lastIndex; + Alignment = alignment; } } - public static ParseResult Parse(ReadOnlySpan format) + internal const int ArgLengthLimit = 16; + internal const int WidthLimit = 1000; // Note: -WidthLimit < ArgAlign < WidthLimit + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ParserScanResult ScanFormatString(ReadOnlySpan format, ref int i) { - int index = -1; - var formatStart = -1; + var len = format.Length; + char c = format[i]; - // ignore start '{' - for (int i = 1; i < format.Length; i++) + i++; // points netxt char + if (c == '}') { - if (format[i] == '}') + // skip escaped '}' + if (i < len && format[i] == '}') + { + i++; + return ParserScanResult.EscapedChar; + } + else + { + ExceptionUtil.ThrowFormatError(); + return ParserScanResult.NormalChar; // NOTE Don't reached + } + } + else if (c == '{') + { + // skip escaped '{' + if (i < len && format[i] == '{') + { + i++; + return ParserScanResult.EscapedChar; + } + else { - if (index == -1) + i--; + return ParserScanResult.BraceOpen; + } + } + else + { + // ch is the normal char OR end of text + return ParserScanResult.NormalChar; + } + } + + // Accept only non-unicode numbers + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsDigit(char c) => '0' <= c && c <= '9'; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ParseResult Parse(string format, int i) + { + char c = default; + var len = format.Length; + + i++; // Skip `{` + + // === Index Component === + // ('0'-'9')+ WS* + + if (i == len || !IsDigit(c = format[i])) + { + ExceptionUtil.ThrowFormatError(); + } + + int paramIndex = 0; + do + { + paramIndex = (paramIndex * 10) + c - '0'; + + if (++i == len) + ExceptionUtil.ThrowFormatError(); + + c = format[i]; + } + while (IsDigit(c) && paramIndex < ArgLengthLimit); + + if (paramIndex >= ArgLengthLimit) + { + ExceptionUtil.ThrowFormatException(); + } + + // skip whitespace. + while (i < len && (c = format[i]) == ' ') + i++; + + // === Alignment Component === + // comma WS* minus? ('0'-'9')+ WS* + + int alignment = 0; + + if (c == ',') + { + i++; + + // skip whitespace. + while (i < len && (c = format[i]) == ' ') + i++; + + if (i == len) + { + ExceptionUtil.ThrowFormatError(); + } + + var leftJustify = false; + if (c == '-') + { + leftJustify = true; + + if (++i == len) + ExceptionUtil.ThrowFormatError(); + + c = format[i]; + } + + if (!IsDigit(c)) + { + ExceptionUtil.ThrowFormatError(); + } + + do + { + alignment = (alignment * 10) + c - '0'; + + if (++i == len) + ExceptionUtil.ThrowFormatError(); + + c = format[i]; + } + while (IsDigit(c) && alignment < WidthLimit); + + if (leftJustify) + alignment *= -1; + } + + // skip whitespace. + while (i < len && (c = format[i]) == ' ') + i++; + + // === Format String Component === + + ReadOnlySpan itemFormatSpan = default; + + if (c == ':') + { + i++; + int formatStart = i; + + while (true) + { + if (i == len) { - index = Int32.Parse(format.Slice(1, i - 1)); - return new ParseResult(index, default, i); + ExceptionUtil.ThrowFormatError(); } - else + c = format[i]; + + if (c == '}') { - var formatString = format.Slice(formatStart, i - formatStart); - return new ParseResult(index, formatString, i); + break; } + else if (c == '{') + { + ExceptionUtil.ThrowFormatError(); + } + + i++; } - if (index == -1 && (format[i] == ',' && format[i - 1] != '\\') || (format[i] == ':' && format[i - 1] != '\\')) + // has format + if (i > formatStart) { - index = Int32.Parse(format.Slice(1, i - 1)); - formatStart = i + 1; + itemFormatSpan = format.AsSpan(formatStart, i - formatStart); } } + else if (c != '}') + { + // Unexpected character + ExceptionUtil.ThrowFormatError(); + } - throw new FormatException("Invalid format string. format:" + format.ToString()); + i++; // Skip `}` + return new ParseResult(paramIndex, itemFormatSpan, i, alignment); } } + internal enum ParserScanResult + { + BraceOpen, + EscapedChar, + NormalChar, + } + } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs index c343a572..8d5210fa 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs @@ -46,40 +46,25 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1) { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + switch (item.FormatIndex) + { + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -122,55 +107,30 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -213,70 +173,35 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -319,85 +244,40 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -440,100 +320,45 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -576,115 +401,50 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -727,130 +487,55 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -893,145 +578,60 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1074,160 +674,65 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1270,175 +775,70 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1481,190 +881,75 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1707,205 +992,80 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1948,220 +1108,85 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -2204,235 +1229,90 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -2475,250 +1355,95 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - case 14: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } + case 14: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -2761,265 +1486,100 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - case 14: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - sb.Advance(argWritten); - break; - } - case 15: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg16)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } + case 14: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + break; + } + case 15: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg16, nameof(arg16)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3062,41 +1622,26 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1) { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3139,56 +1684,31 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3231,71 +1751,36 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3338,86 +1823,41 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3460,101 +1900,46 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3597,116 +1982,51 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3749,131 +2069,56 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3916,146 +2161,61 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4098,161 +2258,66 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4295,176 +2360,71 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4507,191 +2467,76 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4734,206 +2579,81 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4976,221 +2696,86 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -5233,236 +2818,91 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -5505,251 +2945,96 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - case 14: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } + case 14: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -5792,264 +3077,99 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - case 14: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - sb.Advance(argWritten); - break; - } - case 15: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg16)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } + case 14: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + break; + } + case 15: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg16, nameof(arg16)); + break; + } } } } } - -} \ No newline at end of file +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs index 60bdcfd9..048c55d0 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.Diagnostics; namespace Cysharp.Text { @@ -8,97 +9,92 @@ internal static class PreparedFormatHelper { internal static FormatSegment[] Parse(string format, bool withStandardFormat) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var list = new List(); + int i = 0; + int len = format.Length; + var copyFrom = 0; - for (int i = 0; i < format.Length; i++) + var formatSpan = format.AsSpan(); + + while (true) { - if (format[i] == '{') + while (i < len) { - // escape. - if (i == format.Length - 1) + var parserScanResult = FormatParser.ScanFormatString(formatSpan, ref i); + + if (ParserScanResult.NormalChar == parserScanResult && i < len) { - throw new FormatException("invalid format"); + // skip normal char + continue; } - if (i != format.Length && format[i + 1] == '{') + var size = i - copyFrom; + if (ParserScanResult.EscapedChar == parserScanResult) { - var size = i - copyFrom; - if (size != 0) - { - list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); - } - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; + size--; } - else + + if (size != 0) { - var size = i - copyFrom; - if (size != 0) - { - list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); - } + list.Add(new FormatSegment(copyFrom, size, FormatSegment.NotFormatIndex, format, default, 0)); } - // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - list.Add(new FormatSegment(0, 0, true, indexParse.Index, indexParse.FormatString.ToString(), withStandardFormat)); + copyFrom = i; - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; - } - else if (format[i] == '}') - { - if (i != format.Length && format[i + 1] == '}') + if (ParserScanResult.BraceOpen == parserScanResult) { - var size = i - copyFrom; - if (size != 0) - { - list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); - } - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; + break; } } - } - { - // final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) + if (i >= len) { - list.Add(new FormatSegment(copyFrom, copyLength, false, 0, null, withStandardFormat)); + break; } + + // Here it is before `{`. + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; // continue after '}' + i = indexParse.LastIndex; + + list.Add(new FormatSegment(indexParse.LastIndex - indexParse.FormatString.Length - 1, indexParse.FormatString.Length, indexParse.Index, format, withStandardFormat, indexParse.Alignment)); + } return list.ToArray(); } } - internal readonly struct FormatSegment { + public const int NotFormatIndex = -1; + public readonly int Offset; public readonly int Count; - public readonly bool IsFormatArgument; + public bool IsFormatArgument => FormatIndex != NotFormatIndex; public readonly int FormatIndex; public readonly string FormatString; + public readonly int Alignment; // Utf8 public readonly StandardFormat StandardFormat; - public FormatSegment(int offset, int count, bool isFormatArgument, int formatIndex, string formatString, bool utf8) + public FormatSegment(int offset, int count, int formatIndex, string formatString, bool utf8, int alignment) { Offset = offset; Count = count; - IsFormatArgument = isFormatArgument; FormatIndex = formatIndex; FormatString = formatString; + Alignment = alignment; if (utf8) { - StandardFormat = (formatString != null) ? StandardFormat.Parse(formatString) : default; + StandardFormat = (formatString != null) ? StandardFormat.Parse(formatString.AsSpan(Offset, Count)) : default; } else { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 515186d2..717464b7 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -7,10 +7,16 @@ public partial struct Utf16ValueStringBuilder /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -33,22 +39,22 @@ public void AppendFormat(string format, T1 arg1) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -56,6 +62,10 @@ public void AppendFormat(string format, T1 arg1) copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -68,14 +78,19 @@ public void AppendFormat(string format, T1 arg1) } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -98,25 +113,25 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -124,6 +139,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -136,14 +155,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -166,28 +190,28 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -195,6 +219,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -207,14 +235,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -237,31 +270,31 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -269,6 +302,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -281,14 +318,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -311,34 +353,34 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -346,6 +388,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -358,14 +404,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -388,37 +439,37 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -426,6 +477,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -438,14 +493,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -468,40 +528,40 @@ public void AppendFormat(string format, T1 arg1, T2 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -509,6 +569,10 @@ public void AppendFormat(string format, T1 arg1, T2 copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -521,14 +585,19 @@ public void AppendFormat(string format, T1 arg1, T2 } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -551,43 +620,43 @@ public void AppendFormat(string format, T1 arg1, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -595,6 +664,10 @@ public void AppendFormat(string format, T1 arg1, copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -607,14 +680,19 @@ public void AppendFormat(string format, T1 arg1, } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -637,46 +715,46 @@ public void AppendFormat(string format, T1 a } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -684,6 +762,10 @@ public void AppendFormat(string format, T1 a copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -696,14 +778,19 @@ public void AppendFormat(string format, T1 a } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -726,49 +813,49 @@ public void AppendFormat(string format, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -776,6 +863,10 @@ public void AppendFormat(string format, copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -788,14 +879,19 @@ public void AppendFormat(string format, } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -818,52 +914,52 @@ public void AppendFormat(string fo } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -871,6 +967,10 @@ public void AppendFormat(string fo copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -883,14 +983,19 @@ public void AppendFormat(string fo } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -913,55 +1018,55 @@ public void AppendFormat(stri } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); continue; case 11: - AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -969,6 +1074,10 @@ public void AppendFormat(stri copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -981,14 +1090,19 @@ public void AppendFormat(stri } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1011,58 +1125,58 @@ public void AppendFormat } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); continue; case 11: - AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); continue; case 12: - AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + AppendFormatInternal(arg13, indexParse.Alignment, indexParse.FormatString, nameof(arg13)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -1070,6 +1184,10 @@ public void AppendFormat copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -1082,14 +1200,19 @@ public void AppendFormat } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1112,61 +1235,61 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1216,64 +1348,64 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1323,67 +1464,67 @@ public void AppendFormat(T arg, int width, ReadOnlySpan format, string argName) + { + if (width <= 0) // leftJustify + { + width *= -1; + + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format)) + { + Grow(charsWritten); + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format)) + { + ThrowArgumentException(argName); + } + } + + index += charsWritten; + + int padding = width - charsWritten; + if (width > 0 && padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + + Append(s); + } + else + { + Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc char[s.Length * 2]; + if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + + Append(s.Slice(0, charsWritten)); + } + } + } static void ThrowNestedException() { @@ -665,4 +728,4 @@ static bool TryFormatDefault(T value, Span dest, out int written, ReadOnly } } } -} \ No newline at end of file +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index 8fd66bc9..4f0b1ad7 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -8,10 +8,16 @@ public partial struct Utf8ValueStringBuilder /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -34,28 +40,33 @@ public void AppendFormat(string format, T1 arg1) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -74,10 +85,16 @@ public void AppendFormat(string format, T1 arg1) /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -100,31 +117,36 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -143,10 +165,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -169,34 +197,39 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -215,10 +248,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -241,37 +280,42 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -290,10 +334,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -316,40 +366,45 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -368,10 +423,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -394,43 +455,48 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -449,10 +515,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -475,46 +547,51 @@ public void AppendFormat(string format, T1 arg1, T2 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -533,10 +610,16 @@ public void AppendFormat(string format, T1 arg1, T2 /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -559,49 +642,54 @@ public void AppendFormat(string format, T1 arg1, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -620,10 +708,16 @@ public void AppendFormat(string format, T1 arg1, /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -646,52 +740,57 @@ public void AppendFormat(string format, T1 a } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -710,10 +809,16 @@ public void AppendFormat(string format, T1 a /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -736,55 +841,60 @@ public void AppendFormat(string format, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -803,10 +913,16 @@ public void AppendFormat(string format, /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -829,58 +945,63 @@ public void AppendFormat(string fo } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -899,10 +1020,16 @@ public void AppendFormat(string fo /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -925,61 +1052,66 @@ public void AppendFormat(stri } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; case 11: - AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -998,10 +1130,16 @@ public void AppendFormat(stri /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1024,64 +1162,69 @@ public void AppendFormat } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; case 11: - AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); continue; case 12: - AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + AppendFormatInternal(arg13, indexParse.Alignment, writeFormat, nameof(arg13)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -1100,10 +1243,16 @@ public void AppendFormat /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1126,67 +1275,72 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1231,70 +1391,75 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1339,73 +1510,78 @@ public void AppendFormat, const int ThreadStaticBufferSize = 64444; const int DefaultBufferSize = 65536; // use 64K default buffer. - static Encoding UTF8NoBom = new UTF8Encoding(false); + internal static readonly Encoding UTF8NoBom = new UTF8Encoding(false); static byte newLine1; static byte newLine2; @@ -366,19 +366,66 @@ static void ThrowNestedException() throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); } - private void AppendFormatInternal(T arg, StandardFormat writeFormat, string argName) + private void AppendFormatInternal(T arg, int width, StandardFormat format, string argName) { - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var written, writeFormat)) + if (width <= 0) // leftJustify { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out written, writeFormat)) + width *= -1; + + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format)) { - ThrowArgumentException(argName); + Grow(charsWritten); + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format)) + { + ThrowArgumentException(argName); + } + } + + index += charsWritten; + + int padding = width - charsWritten; + if (width > 0 && padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. } } - index += written; - } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + + Append(s); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ThrowArgumentException(argName); + } + } + int padding = width - charsWritten; + if (padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + + s.CopyTo(GetSpan(charsWritten)); + Advance(charsWritten); + } + } + } /// /// Register custom formatter @@ -455,4 +502,4 @@ static bool TryFormatDefault(T value, Span dest, out int written, Standard } } } -} \ No newline at end of file +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs index dcf7f395..0756b1f6 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs @@ -1,6 +1,8 @@ -using System.Runtime.CompilerServices; +using System; using System.Buffers; -using System; +using System.Runtime.CompilerServices; + +using static Cysharp.Text.Utf8ValueStringBuilder; namespace Cysharp.Text { @@ -9,10 +11,16 @@ public static partial class ZString /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -39,27 +47,15 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -67,9 +63,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -77,11 +73,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -99,10 +97,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -129,42 +133,18 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -172,9 +152,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -182,11 +162,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -204,10 +186,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -234,57 +222,21 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -292,9 +244,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -302,11 +254,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -324,10 +278,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -354,72 +314,24 @@ public static void Utf8Format(IBufferWriter bufferWriter, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -427,9 +339,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -437,11 +349,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -459,10 +373,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -489,87 +409,27 @@ public static void Utf8Format(IBufferWriter bufferWrit } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -577,9 +437,9 @@ public static void Utf8Format(IBufferWriter bufferWrit ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -587,11 +447,13 @@ public static void Utf8Format(IBufferWriter bufferWrit bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -609,10 +471,16 @@ public static void Utf8Format(IBufferWriter bufferWrit /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -639,102 +507,30 @@ public static void Utf8Format(IBufferWriter buffer } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -742,9 +538,9 @@ public static void Utf8Format(IBufferWriter buffer ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -752,11 +548,13 @@ public static void Utf8Format(IBufferWriter buffer bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -774,10 +572,16 @@ public static void Utf8Format(IBufferWriter buffer /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -804,117 +608,33 @@ public static void Utf8Format(IBufferWriter bu } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -922,9 +642,9 @@ public static void Utf8Format(IBufferWriter bu ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -932,11 +652,13 @@ public static void Utf8Format(IBufferWriter bu bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -954,10 +676,16 @@ public static void Utf8Format(IBufferWriter bu /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -984,132 +712,36 @@ public static void Utf8Format(IBufferWriter.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -1117,9 +749,9 @@ public static void Utf8Format(IBufferWriter(IBufferWriter(IBufferWriterReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1179,147 +819,39 @@ public static void Utf8Format(IBufferWriter< } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -1327,9 +859,9 @@ public static void Utf8Format(IBufferWriter< ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -1337,11 +869,13 @@ public static void Utf8Format(IBufferWriter< bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -1359,10 +893,16 @@ public static void Utf8Format(IBufferWriter< /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1389,162 +929,42 @@ public static void Utf8Format(IBufferWr } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -1552,9 +972,9 @@ public static void Utf8Format(IBufferWr ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -1562,11 +982,13 @@ public static void Utf8Format(IBufferWr bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -1584,10 +1006,16 @@ public static void Utf8Format(IBufferWr /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1614,177 +1042,45 @@ public static void Utf8Format(IBuf } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -1792,9 +1088,9 @@ public static void Utf8Format(IBuf ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -1802,11 +1098,13 @@ public static void Utf8Format(IBuf bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -1824,10 +1122,16 @@ public static void Utf8Format(IBuf /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1854,192 +1158,48 @@ public static void Utf8Format } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -2047,9 +1207,9 @@ public static void Utf8Format ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -2057,11 +1217,13 @@ public static void Utf8Format bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -2079,10 +1241,16 @@ public static void Utf8Format /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -2109,207 +1277,51 @@ public static void Utf8Format.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; case 12: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -2317,9 +1329,9 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -2379,222 +1399,54 @@ public static void Utf8Format.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; case 12: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); + continue; case 13: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -2602,9 +1454,9 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -2664,237 +1524,57 @@ public static void Utf8Format.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; case 12: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); + continue; case 13: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); + continue; case 14: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg15, indexParse.Alignment, writeFormat, nameof(arg15)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -2902,9 +1582,9 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -2964,252 +1652,60 @@ public static void Utf8Format.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; case 12: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); + continue; case 13: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); + continue; case 14: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg15, indexParse.Alignment, writeFormat, nameof(arg15)); + continue; case 15: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg16)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg16, indexParse.Alignment, writeFormat, nameof(arg16)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -3217,9 +1713,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, T arg, int width, StandardFormat format, string argName) + { + if (width <= 0) // leftJustify + { + width *= -1; + + var buffer = bufferWriter.GetSpan(); + + if (!FormatterCache.TryFormatDelegate(arg, buffer, out var written, format)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + + if (!FormatterCache.TryFormatDelegate(arg, buffer, out written, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + bufferWriter.Advance(written); + + int padding = width - written; + if (width > 0 && padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + + ZString.AppendChars(ref bufferWriter, s.AsSpan()); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + + s.CopyTo(bufferWriter.GetSpan(charsWritten)); + bufferWriter.Advance(charsWritten); + } + } + } + } -} \ No newline at end of file +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs index 6a48bb20..aa4cb110 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.cs @@ -11,6 +11,14 @@ public static partial class ZString { static Encoding UTF8NoBom = new UTF8Encoding(false); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void AppendChars(ref TBufferWriter sb, ReadOnlySpan chars) + where TBufferWriter : System.Buffers.IBufferWriter + { + var span = sb.GetSpan(UTF8NoBom.GetMaxByteCount(chars.Length)); + sb.Advance(UTF8NoBom.GetBytes(chars, span)); + } + /// Create the Utf16 string StringBuilder. public static Utf16ValueStringBuilder CreateStringBuilder() { diff --git a/src/ZString/ExceptionUtil.cs b/src/ZString/ExceptionUtil.cs index 64413691..401e1c65 100644 --- a/src/ZString/ExceptionUtil.cs +++ b/src/ZString/ExceptionUtil.cs @@ -15,5 +15,10 @@ internal static void ThrowFormatException() { throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + + internal static void ThrowFormatError() + { + throw new FormatException("Input string was not in a correct format."); + } } } diff --git a/src/ZString/FormatHelper.cs b/src/ZString/FormatHelper.cs new file mode 100644 index 00000000..5e23b582 --- /dev/null +++ b/src/ZString/FormatHelper.cs @@ -0,0 +1,162 @@ +using System; +using System.Text; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ + internal static partial class Utf16PreparedFormat + { + public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + where TBufferWriter : IBufferWriter + { + const char sp = (char)' '; + var width = item.Alignment; + var format = item.FormatString.AsSpan(item.Offset, item.Count); + + if (width <= 0) // leftJustify + { + width *= -1; + + var span = sb.GetSpan(0); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out argWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + sb.Advance(argWritten); + + int padding = width - argWritten; + if (width > 0 && padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + var span = sb.GetSpan(s.Length); + s.AsSpan().CopyTo(span); + sb.Advance(s.Length); + } + else + { + Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc char[s.Length * 2]; + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); + } + } + } + } + internal static partial class Utf8PreparedFormat + { + public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + where TBufferWriter : IBufferWriter + { + const byte sp = (byte)' '; + var width = item.Alignment; + var format = item.StandardFormat; + + if (width <= 0) // leftJustify + { + width *= -1; + + var span = sb.GetSpan(0); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out argWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + sb.Advance(argWritten); + + int padding = width - argWritten; + if (width > 0 && padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + ZString.AppendChars(ref sb, s.AsSpan()); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); + } + } + } + } +} diff --git a/src/ZString/FormatHelper.tt b/src/ZString/FormatHelper.tt new file mode 100644 index 00000000..db3f1c89 --- /dev/null +++ b/src/ZString/FormatHelper.tt @@ -0,0 +1,99 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<#@ include file="T4Common.t4" once="true" #> +using System; +using System.Text; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace Cysharp.Text +{ +<# foreach(var utf in utfTypes ) { var isUtf16 = (utf == "Utf16"); var elemType = isUtf16 ? "char" : "byte"; #> + internal static partial class <#= utf #>PreparedFormat + { + public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + where TBufferWriter : IBufferWriter<<#= elemType #>> + { + const <#= elemType #> sp = (<#= elemType #>)' '; + var width = item.Alignment; + var format = <#= isUtf16 ? "item.FormatString.AsSpan(item.Offset, item.Count)" : "item.StandardFormat" #>; + + if (width <= 0) // leftJustify + { + width *= -1; + + var span = sb.GetSpan(0); + if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) + { + sb.Advance(0); + span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); + if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out argWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + sb.Advance(argWritten); + + int padding = width - argWritten; + if (width > 0 && padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + +<# if(isUtf16) { #> + var span = sb.GetSpan(s.Length); + s.AsSpan().CopyTo(span); + sb.Advance(s.Length); +<# }else { #> + ZString.AppendChars(ref sb, s.AsSpan()); +<# } #> + } + else + { + Span<<#= elemType #>> s = stackalloc <#= elemType #>[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc <#= elemType #>[s.Length * 2]; + if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); + } + } + } + } +<# } // foreach(utf) #> +} diff --git a/src/ZString/FormatParser.cs b/src/ZString/FormatParser.cs index eed62867..a9552815 100644 --- a/src/ZString/FormatParser.cs +++ b/src/ZString/FormatParser.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; namespace Cysharp.Text { @@ -11,45 +12,207 @@ public readonly ref struct ParseResult public readonly int Index; public readonly ReadOnlySpan FormatString; public readonly int LastIndex; + public readonly int Alignment; - public ParseResult(int index, ReadOnlySpan formatString, int lastIndex) + public ParseResult(int index, ReadOnlySpan formatString, int lastIndex, int alignment) { Index = index; FormatString = formatString; LastIndex = lastIndex; + Alignment = alignment; } } - public static ParseResult Parse(ReadOnlySpan format) + internal const int ArgLengthLimit = 16; + internal const int WidthLimit = 1000; // Note: -WidthLimit < ArgAlign < WidthLimit + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ParserScanResult ScanFormatString(ReadOnlySpan format, ref int i) { - int index = -1; - var formatStart = -1; + var len = format.Length; + char c = format[i]; - // ignore start '{' - for (int i = 1; i < format.Length; i++) + i++; // points netxt char + if (c == '}') { - if (format[i] == '}') + // skip escaped '}' + if (i < len && format[i] == '}') + { + i++; + return ParserScanResult.EscapedChar; + } + else + { + ExceptionUtil.ThrowFormatError(); + return ParserScanResult.NormalChar; // NOTE Don't reached + } + } + else if (c == '{') + { + // skip escaped '{' + if (i < len && format[i] == '{') + { + i++; + return ParserScanResult.EscapedChar; + } + else { - if (index == -1) + i--; + return ParserScanResult.BraceOpen; + } + } + else + { + // ch is the normal char OR end of text + return ParserScanResult.NormalChar; + } + } + + // Accept only non-unicode numbers + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsDigit(char c) => '0' <= c && c <= '9'; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ParseResult Parse(string format, int i) + { + char c = default; + var len = format.Length; + + i++; // Skip `{` + + // === Index Component === + // ('0'-'9')+ WS* + + if (i == len || !IsDigit(c = format[i])) + { + ExceptionUtil.ThrowFormatError(); + } + + int paramIndex = 0; + do + { + paramIndex = (paramIndex * 10) + c - '0'; + + if (++i == len) + ExceptionUtil.ThrowFormatError(); + + c = format[i]; + } + while (IsDigit(c) && paramIndex < ArgLengthLimit); + + if (paramIndex >= ArgLengthLimit) + { + ExceptionUtil.ThrowFormatException(); + } + + // skip whitespace. + while (i < len && (c = format[i]) == ' ') + i++; + + // === Alignment Component === + // comma WS* minus? ('0'-'9')+ WS* + + int alignment = 0; + + if (c == ',') + { + i++; + + // skip whitespace. + while (i < len && (c = format[i]) == ' ') + i++; + + if (i == len) + { + ExceptionUtil.ThrowFormatError(); + } + + var leftJustify = false; + if (c == '-') + { + leftJustify = true; + + if (++i == len) + ExceptionUtil.ThrowFormatError(); + + c = format[i]; + } + + if (!IsDigit(c)) + { + ExceptionUtil.ThrowFormatError(); + } + + do + { + alignment = (alignment * 10) + c - '0'; + + if (++i == len) + ExceptionUtil.ThrowFormatError(); + + c = format[i]; + } + while (IsDigit(c) && alignment < WidthLimit); + + if (leftJustify) + alignment *= -1; + } + + // skip whitespace. + while (i < len && (c = format[i]) == ' ') + i++; + + // === Format String Component === + + ReadOnlySpan itemFormatSpan = default; + + if (c == ':') + { + i++; + int formatStart = i; + + while (true) + { + if (i == len) { - index = Int32.Parse(format.Slice(1, i - 1)); - return new ParseResult(index, default, i); + ExceptionUtil.ThrowFormatError(); } - else + c = format[i]; + + if (c == '}') { - var formatString = format.Slice(formatStart, i - formatStart); - return new ParseResult(index, formatString, i); + break; } + else if (c == '{') + { + ExceptionUtil.ThrowFormatError(); + } + + i++; } - if (index == -1 && (format[i] == ',' && format[i - 1] != '\\') || (format[i] == ':' && format[i - 1] != '\\')) + // has format + if (i > formatStart) { - index = Int32.Parse(format.Slice(1, i - 1)); - formatStart = i + 1; + itemFormatSpan = format.AsSpan(formatStart, i - formatStart); } } + else if (c != '}') + { + // Unexpected character + ExceptionUtil.ThrowFormatError(); + } - throw new FormatException("Invalid format string. format:" + format.ToString()); + i++; // Skip `}` + return new ParseResult(paramIndex, itemFormatSpan, i, alignment); } } + internal enum ParserScanResult + { + BraceOpen, + EscapedChar, + NormalChar, + } + } diff --git a/src/ZString/PreparedFormat.cs b/src/ZString/PreparedFormat.cs index c343a572..8d5210fa 100644 --- a/src/ZString/PreparedFormat.cs +++ b/src/ZString/PreparedFormat.cs @@ -46,40 +46,25 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1) { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + switch (item.FormatIndex) + { + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -122,55 +107,30 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -213,70 +173,35 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -319,85 +244,40 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -440,100 +320,45 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -576,115 +401,50 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -727,130 +487,55 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -893,145 +578,60 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1074,160 +674,65 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1270,175 +775,70 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1481,190 +881,75 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1707,205 +992,80 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -1948,220 +1108,85 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -2204,235 +1229,90 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -2475,250 +1355,95 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - case 14: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } + case 14: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + break; + } } } } } - public sealed partial class Utf16PreparedFormat { public string FormatString { get; } @@ -2761,265 +1486,100 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - case 14: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - sb.Advance(argWritten); - break; - } - case 15: - { - var span = sb.GetSpan(0); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out var argWritten, item.FormatString.AsSpan())) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out argWritten, item.FormatString.AsSpan())) - { - ExceptionUtil.ThrowArgumentException(nameof(arg16)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); + } + break; + case 0: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } + case 14: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + break; + } + case 15: + { + Utf16PreparedFormat.FormatTo(ref sb, item, arg16, nameof(arg16)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3062,41 +1622,26 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1) { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3139,56 +1684,31 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3231,71 +1751,36 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3338,86 +1823,41 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3460,101 +1900,46 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3597,116 +1982,51 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3749,131 +2069,56 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -3916,146 +2161,61 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4098,161 +2258,66 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4295,176 +2360,71 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4507,191 +2467,76 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4734,206 +2579,81 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -4976,221 +2696,86 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) - { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else + switch (item.FormatIndex) { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -5233,236 +2818,91 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -5505,251 +2945,96 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - case 14: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } + case 14: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + break; + } } } } } - public sealed partial class Utf8PreparedFormat { public string FormatString { get; } @@ -5792,264 +3077,99 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); - } - else - { - switch (item.FormatIndex) - { - case 0: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - sb.Advance(argWritten); - break; - } - case 1: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - sb.Advance(argWritten); - break; - } - case 2: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - sb.Advance(argWritten); - break; - } - case 3: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - sb.Advance(argWritten); - break; - } - case 4: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - sb.Advance(argWritten); - break; - } - case 5: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - sb.Advance(argWritten); - break; - } - case 6: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - sb.Advance(argWritten); - break; - } - case 7: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - sb.Advance(argWritten); - break; - } - case 8: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - sb.Advance(argWritten); - break; - } - case 9: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - sb.Advance(argWritten); - break; - } - case 10: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - sb.Advance(argWritten); - break; - } - case 11: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - sb.Advance(argWritten); - break; - } - case 12: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - sb.Advance(argWritten); - break; - } - case 13: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - sb.Advance(argWritten); - break; - } - case 14: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - sb.Advance(argWritten); - break; - } - case 15: - { - var span = sb.GetSpan(0); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out var argWritten, item.StandardFormat)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, span, out argWritten, item.StandardFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg16)); - } - } - sb.Advance(argWritten); - break; - } - default: - break; - } + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); + } + break; + case 0: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + break; + } + case 1: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + break; + } + case 2: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + break; + } + case 3: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + break; + } + case 4: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + break; + } + case 5: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + break; + } + case 6: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + break; + } + case 7: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + break; + } + case 8: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + break; + } + case 9: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + break; + } + case 10: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + break; + } + case 11: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + break; + } + case 12: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + break; + } + case 13: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + break; + } + case 14: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + break; + } + case 15: + { + Utf8PreparedFormat.FormatTo(ref sb, item, arg16, nameof(arg16)); + break; + } } } } } - -} \ No newline at end of file +} diff --git a/src/ZString/PreparedFormat.tt b/src/ZString/PreparedFormat.tt index 4087bea3..b34f0ccb 100644 --- a/src/ZString/PreparedFormat.tt +++ b/src/ZString/PreparedFormat.tt @@ -55,49 +55,34 @@ namespace Cysharp.Text { foreach (var item in segments) { - if (!item.IsFormatArgument) + switch (item.FormatIndex) { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + case FormatSegment.NotFormatIndex: + { + var strSpan = FormatString.AsSpan(item.Offset, item.Count); <# if(isUtf16) { #> - var span = sb.GetSpan(item.Count); - strSpan.TryCopyTo(span); - sb.Advance(item.Count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); <# } else { #> - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var span = sb.GetSpan(size); + var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + sb.Advance(count); <# } #> - } - else - { - switch (item.FormatIndex) - { + } + break; <# for(var j = 0; j < i; j++) { #> - case <#= j #>: - { - var span = sb.GetSpan(0); - if (!<#= utf #>ValueStringBuilder.FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, span, out var argWritten, <#= isUtf16 ? "item.FormatString.AsSpan()" : "item.StandardFormat" #>)) - { - sb.Advance(0); - span = sb.GetSpan(Math.Max(span.Length + 1, argWritten)); - if (!<#= utf #>ValueStringBuilder.FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, span, out argWritten, <#= isUtf16 ? "item.FormatString.AsSpan()" : "item.StandardFormat" #>)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg<#= j + 1 #>)); - } - } - sb.Advance(argWritten); - break; - } -<# } // for(j) #> - default: + case <#= j #>: + { + <#= utf #>PreparedFormat.FormatTo(ref sb, item, arg<#= j + 1 #>, nameof(arg<#= j + 1 #>)); break; - } + } +<# } // for(j) #> } } } } - <# } // for(i) #> <# } // foreach(utf) #> -} \ No newline at end of file +} diff --git a/src/ZString/PreparedFormatHelper.cs b/src/ZString/PreparedFormatHelper.cs index 60bdcfd9..048c55d0 100644 --- a/src/ZString/PreparedFormatHelper.cs +++ b/src/ZString/PreparedFormatHelper.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.Diagnostics; namespace Cysharp.Text { @@ -8,97 +9,92 @@ internal static class PreparedFormatHelper { internal static FormatSegment[] Parse(string format, bool withStandardFormat) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var list = new List(); + int i = 0; + int len = format.Length; + var copyFrom = 0; - for (int i = 0; i < format.Length; i++) + var formatSpan = format.AsSpan(); + + while (true) { - if (format[i] == '{') + while (i < len) { - // escape. - if (i == format.Length - 1) + var parserScanResult = FormatParser.ScanFormatString(formatSpan, ref i); + + if (ParserScanResult.NormalChar == parserScanResult && i < len) { - throw new FormatException("invalid format"); + // skip normal char + continue; } - if (i != format.Length && format[i + 1] == '{') + var size = i - copyFrom; + if (ParserScanResult.EscapedChar == parserScanResult) { - var size = i - copyFrom; - if (size != 0) - { - list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); - } - i = i + 1; // skip escaped '{' - copyFrom = i; - continue; + size--; } - else + + if (size != 0) { - var size = i - copyFrom; - if (size != 0) - { - list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); - } + list.Add(new FormatSegment(copyFrom, size, FormatSegment.NotFormatIndex, format, default, 0)); } - // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - list.Add(new FormatSegment(0, 0, true, indexParse.Index, indexParse.FormatString.ToString(), withStandardFormat)); + copyFrom = i; - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; - } - else if (format[i] == '}') - { - if (i != format.Length && format[i + 1] == '}') + if (ParserScanResult.BraceOpen == parserScanResult) { - var size = i - copyFrom; - if (size != 0) - { - list.Add(new FormatSegment(copyFrom, size, false, 0, null, withStandardFormat)); - } - i = i + 1; // skip escaped '}' - copyFrom = i; - continue; + break; } } - } - { - // final string - var copyLength = format.Length - copyFrom; - if (copyLength > 0) + if (i >= len) { - list.Add(new FormatSegment(copyFrom, copyLength, false, 0, null, withStandardFormat)); + break; } + + // Here it is before `{`. + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; // continue after '}' + i = indexParse.LastIndex; + + list.Add(new FormatSegment(indexParse.LastIndex - indexParse.FormatString.Length - 1, indexParse.FormatString.Length, indexParse.Index, format, withStandardFormat, indexParse.Alignment)); + } return list.ToArray(); } } - internal readonly struct FormatSegment { + public const int NotFormatIndex = -1; + public readonly int Offset; public readonly int Count; - public readonly bool IsFormatArgument; + public bool IsFormatArgument => FormatIndex != NotFormatIndex; public readonly int FormatIndex; public readonly string FormatString; + public readonly int Alignment; // Utf8 public readonly StandardFormat StandardFormat; - public FormatSegment(int offset, int count, bool isFormatArgument, int formatIndex, string formatString, bool utf8) + public FormatSegment(int offset, int count, int formatIndex, string formatString, bool utf8, int alignment) { Offset = offset; Count = count; - IsFormatArgument = isFormatArgument; FormatIndex = formatIndex; FormatString = formatString; + Alignment = alignment; if (utf8) { - StandardFormat = (formatString != null) ? StandardFormat.Parse(formatString) : default; + StandardFormat = (formatString != null) ? StandardFormat.Parse(formatString.AsSpan(Offset, Count)) : default; } else { diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 515186d2..717464b7 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -7,10 +7,16 @@ public partial struct Utf16ValueStringBuilder /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -33,22 +39,22 @@ public void AppendFormat(string format, T1 arg1) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -56,6 +62,10 @@ public void AppendFormat(string format, T1 arg1) copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -68,14 +78,19 @@ public void AppendFormat(string format, T1 arg1) } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -98,25 +113,25 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -124,6 +139,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -136,14 +155,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -166,28 +190,28 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -195,6 +219,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -207,14 +235,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -237,31 +270,31 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -269,6 +302,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -281,14 +318,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -311,34 +353,34 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -346,6 +388,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -358,14 +404,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -388,37 +439,37 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -426,6 +477,10 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -438,14 +493,19 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -468,40 +528,40 @@ public void AppendFormat(string format, T1 arg1, T2 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -509,6 +569,10 @@ public void AppendFormat(string format, T1 arg1, T2 copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -521,14 +585,19 @@ public void AppendFormat(string format, T1 arg1, T2 } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -551,43 +620,43 @@ public void AppendFormat(string format, T1 arg1, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -595,6 +664,10 @@ public void AppendFormat(string format, T1 arg1, copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -607,14 +680,19 @@ public void AppendFormat(string format, T1 arg1, } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -637,46 +715,46 @@ public void AppendFormat(string format, T1 a } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -684,6 +762,10 @@ public void AppendFormat(string format, T1 a copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -696,14 +778,19 @@ public void AppendFormat(string format, T1 a } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -726,49 +813,49 @@ public void AppendFormat(string format, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -776,6 +863,10 @@ public void AppendFormat(string format, copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -788,14 +879,19 @@ public void AppendFormat(string format, } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -818,52 +914,52 @@ public void AppendFormat(string fo } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -871,6 +967,10 @@ public void AppendFormat(string fo copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -883,14 +983,19 @@ public void AppendFormat(string fo } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -913,55 +1018,55 @@ public void AppendFormat(stri } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); continue; case 11: - AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -969,6 +1074,10 @@ public void AppendFormat(stri copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -981,14 +1090,19 @@ public void AppendFormat(stri } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1011,58 +1125,58 @@ public void AppendFormat } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, indexParse.FormatString, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, indexParse.FormatString, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, indexParse.FormatString, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, indexParse.FormatString, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, indexParse.FormatString, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, indexParse.FormatString, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, indexParse.FormatString, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, indexParse.FormatString, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, indexParse.FormatString, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, indexParse.FormatString, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, indexParse.FormatString, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, indexParse.FormatString, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, indexParse.FormatString, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, indexParse.FormatString, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, indexParse.FormatString, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, indexParse.FormatString, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, indexParse.FormatString, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, indexParse.FormatString, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, indexParse.FormatString, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, indexParse.FormatString, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, indexParse.FormatString, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, indexParse.FormatString, nameof(arg11)); continue; case 11: - AppendFormatInternal(arg12, indexParse.FormatString, nameof(arg12)); + AppendFormatInternal(arg12, indexParse.Alignment, indexParse.FormatString, nameof(arg12)); continue; case 12: - AppendFormatInternal(arg13, indexParse.FormatString, nameof(arg13)); + AppendFormatInternal(arg13, indexParse.Alignment, indexParse.FormatString, nameof(arg13)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -1070,6 +1184,10 @@ public void AppendFormat copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -1082,14 +1200,19 @@ public void AppendFormat } } } - /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1112,61 +1235,61 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1216,64 +1348,64 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1323,67 +1464,67 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -41,14 +47,14 @@ namespace Cysharp.Text } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; switch (indexParse.Index) { <# for(var j = 0; j < i; j++) { #> case <#= j #>: - AppendFormatInternal(arg<#= j + 1 #>, indexParse.FormatString, nameof(arg<#= j + 1 #>)); + AppendFormatInternal(arg<#= j + 1 #>, indexParse.Alignment, indexParse.FormatString, nameof(arg<#= j + 1 #>)); continue; <# } #> default: @@ -56,9 +62,9 @@ namespace Cysharp.Text break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); @@ -66,6 +72,10 @@ namespace Cysharp.Text copyFrom = i; continue; } + else + { + ThrowFormatException(); + } } } @@ -78,7 +88,6 @@ namespace Cysharp.Text } } } - <# } #> } } diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 7a4368a6..ed401d7a 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -554,11 +554,74 @@ void ThrowArgumentException(string paramName) { throw new ArgumentException("Can't format argument.", paramName); } - - void ThrowFormatException() + static void ThrowFormatException() { throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } + private static void FormatError() + { + throw new FormatException("Input string was not in a correct format."); + } + + void AppendFormatInternal(T arg, int width, ReadOnlySpan format, string argName) + { + if (width <= 0) // leftJustify + { + width *= -1; + + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format)) + { + Grow(charsWritten); + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format)) + { + ThrowArgumentException(argName); + } + } + + index += charsWritten; + + int padding = width - charsWritten; + if (width > 0 && padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + + Append(s); + } + else + { + Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc char[s.Length * 2]; + if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + + Append(s.Slice(0, charsWritten)); + } + } + } static void ThrowNestedException() { @@ -665,4 +728,4 @@ static bool TryFormatDefault(T value, Span dest, out int written, ReadOnly } } } -} \ No newline at end of file +} diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs index 8fd66bc9..4f0b1ad7 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.AppendFormat.cs @@ -8,10 +8,16 @@ public partial struct Utf8ValueStringBuilder /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -34,28 +40,33 @@ public void AppendFormat(string format, T1 arg1) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -74,10 +85,16 @@ public void AppendFormat(string format, T1 arg1) /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -100,31 +117,36 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -143,10 +165,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -169,34 +197,39 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -215,10 +248,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -241,37 +280,42 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -290,10 +334,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -316,40 +366,45 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -368,10 +423,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -394,43 +455,48 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -449,10 +515,16 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -475,46 +547,51 @@ public void AppendFormat(string format, T1 arg1, T2 } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -533,10 +610,16 @@ public void AppendFormat(string format, T1 arg1, T2 /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -559,49 +642,54 @@ public void AppendFormat(string format, T1 arg1, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -620,10 +708,16 @@ public void AppendFormat(string format, T1 arg1, /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -646,52 +740,57 @@ public void AppendFormat(string format, T1 a } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -710,10 +809,16 @@ public void AppendFormat(string format, T1 a /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -736,55 +841,60 @@ public void AppendFormat(string format, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -803,10 +913,16 @@ public void AppendFormat(string format, /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -829,58 +945,63 @@ public void AppendFormat(string fo } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -899,10 +1020,16 @@ public void AppendFormat(string fo /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -925,61 +1052,66 @@ public void AppendFormat(stri } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; case 11: - AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -998,10 +1130,16 @@ public void AppendFormat(stri /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1024,64 +1162,69 @@ public void AppendFormat } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - AppendFormatInternal(arg1, writeFormat, nameof(arg1)); + AppendFormatInternal(arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - AppendFormatInternal(arg2, writeFormat, nameof(arg2)); + AppendFormatInternal(arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - AppendFormatInternal(arg3, writeFormat, nameof(arg3)); + AppendFormatInternal(arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - AppendFormatInternal(arg4, writeFormat, nameof(arg4)); + AppendFormatInternal(arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - AppendFormatInternal(arg5, writeFormat, nameof(arg5)); + AppendFormatInternal(arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - AppendFormatInternal(arg6, writeFormat, nameof(arg6)); + AppendFormatInternal(arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - AppendFormatInternal(arg7, writeFormat, nameof(arg7)); + AppendFormatInternal(arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - AppendFormatInternal(arg8, writeFormat, nameof(arg8)); + AppendFormatInternal(arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - AppendFormatInternal(arg9, writeFormat, nameof(arg9)); + AppendFormatInternal(arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - AppendFormatInternal(arg10, writeFormat, nameof(arg10)); + AppendFormatInternal(arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - AppendFormatInternal(arg11, writeFormat, nameof(arg11)); + AppendFormatInternal(arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; case 11: - AppendFormatInternal(arg12, writeFormat, nameof(arg12)); + AppendFormatInternal(arg12, indexParse.Alignment, writeFormat, nameof(arg12)); continue; case 12: - AppendFormatInternal(arg13, writeFormat, nameof(arg13)); + AppendFormatInternal(arg13, indexParse.Alignment, writeFormat, nameof(arg13)); continue; default: ThrowFormatException(); break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } @@ -1100,10 +1243,16 @@ public void AppendFormat /// Appends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1126,67 +1275,72 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1231,70 +1391,75 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1339,73 +1510,78 @@ public void AppendFormatAppends the string returned by processing a composite format string, each format item is replaced by the string representation of arguments. public void AppendFormat<<#= CreateTypeArgument(i) #>>(string format, <#= CreateParameters(i) #>) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -42,15 +48,15 @@ namespace Cysharp.Text } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { <# for(var j = 0; j < i; j++) { #> case <#= j #>: - AppendFormatInternal(arg<#= j + 1 #>, writeFormat, nameof(arg<#= j + 1 #>)); + AppendFormatInternal(arg<#= j + 1 #>, indexParse.Alignment, writeFormat, nameof(arg<#= j + 1 #>)); continue; <# } #> default: @@ -58,14 +64,19 @@ namespace Cysharp.Text break; } } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; Append(format.AsSpan(copyFrom, size)); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ThrowFormatException(); } } diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 5acbf83a..2c4c822c 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -13,7 +13,7 @@ public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter, const int ThreadStaticBufferSize = 64444; const int DefaultBufferSize = 65536; // use 64K default buffer. - static Encoding UTF8NoBom = new UTF8Encoding(false); + internal static readonly Encoding UTF8NoBom = new UTF8Encoding(false); static byte newLine1; static byte newLine2; @@ -366,19 +366,66 @@ static void ThrowNestedException() throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); } - private void AppendFormatInternal(T arg, StandardFormat writeFormat, string argName) + private void AppendFormatInternal(T arg, int width, StandardFormat format, string argName) { - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var written, writeFormat)) + if (width <= 0) // leftJustify { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out written, writeFormat)) + width *= -1; + + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out var charsWritten, format)) { - ThrowArgumentException(argName); + Grow(charsWritten); + if (!FormatterCache.TryFormatDelegate(arg, buffer.AsSpan(index), out charsWritten, format)) + { + ThrowArgumentException(argName); + } + } + + index += charsWritten; + + int padding = width - charsWritten; + if (width > 0 && padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. } } - index += written; - } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + + Append(s); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ThrowArgumentException(argName); + } + } + int padding = width - charsWritten; + if (padding > 0) + { + Append(' ', padding); // TODO Fill Method is too slow. + } + + s.CopyTo(GetSpan(charsWritten)); + Advance(charsWritten); + } + } + } /// /// Register custom formatter @@ -455,4 +502,4 @@ static bool TryFormatDefault(T value, Span dest, out int written, Standard } } } -} \ No newline at end of file +} diff --git a/src/ZString/ZString.Utf8Format.cs b/src/ZString/ZString.Utf8Format.cs index dcf7f395..0756b1f6 100644 --- a/src/ZString/ZString.Utf8Format.cs +++ b/src/ZString/ZString.Utf8Format.cs @@ -1,6 +1,8 @@ -using System.Runtime.CompilerServices; +using System; using System.Buffers; -using System; +using System.Runtime.CompilerServices; + +using static Cysharp.Text.Utf8ValueStringBuilder; namespace Cysharp.Text { @@ -9,10 +11,16 @@ public static partial class ZString /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -39,27 +47,15 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -67,9 +63,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -77,11 +73,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -99,10 +97,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -129,42 +133,18 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -172,9 +152,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -182,11 +162,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -204,10 +186,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -234,57 +222,21 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -292,9 +244,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -302,11 +254,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -324,10 +278,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -354,72 +314,24 @@ public static void Utf8Format(IBufferWriter bufferWriter, } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -427,9 +339,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -437,11 +349,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -459,10 +373,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -489,87 +409,27 @@ public static void Utf8Format(IBufferWriter bufferWrit } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -577,9 +437,9 @@ public static void Utf8Format(IBufferWriter bufferWrit ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -587,11 +447,13 @@ public static void Utf8Format(IBufferWriter bufferWrit bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -609,10 +471,16 @@ public static void Utf8Format(IBufferWriter bufferWrit /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -639,102 +507,30 @@ public static void Utf8Format(IBufferWriter buffer } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -742,9 +538,9 @@ public static void Utf8Format(IBufferWriter buffer ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -752,11 +548,13 @@ public static void Utf8Format(IBufferWriter buffer bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -774,10 +572,16 @@ public static void Utf8Format(IBufferWriter buffer /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -804,117 +608,33 @@ public static void Utf8Format(IBufferWriter bu } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -922,9 +642,9 @@ public static void Utf8Format(IBufferWriter bu ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -932,11 +652,13 @@ public static void Utf8Format(IBufferWriter bu bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -954,10 +676,16 @@ public static void Utf8Format(IBufferWriter bu /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -984,132 +712,36 @@ public static void Utf8Format(IBufferWriter.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -1117,9 +749,9 @@ public static void Utf8Format(IBufferWriter(IBufferWriter(IBufferWriterReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1179,147 +819,39 @@ public static void Utf8Format(IBufferWriter< } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -1327,9 +859,9 @@ public static void Utf8Format(IBufferWriter< ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -1337,11 +869,13 @@ public static void Utf8Format(IBufferWriter< bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -1359,10 +893,16 @@ public static void Utf8Format(IBufferWriter< /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1389,162 +929,42 @@ public static void Utf8Format(IBufferWr } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -1552,9 +972,9 @@ public static void Utf8Format(IBufferWr ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -1562,11 +982,13 @@ public static void Utf8Format(IBufferWr bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -1584,10 +1006,16 @@ public static void Utf8Format(IBufferWr /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1614,177 +1042,45 @@ public static void Utf8Format(IBuf } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -1792,9 +1088,9 @@ public static void Utf8Format(IBuf ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -1802,11 +1098,13 @@ public static void Utf8Format(IBuf bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -1824,10 +1122,16 @@ public static void Utf8Format(IBuf /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -1854,192 +1158,48 @@ public static void Utf8Format } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { case 0: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -2047,9 +1207,9 @@ public static void Utf8Format ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -2057,11 +1217,13 @@ public static void Utf8Format bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -2079,10 +1241,16 @@ public static void Utf8Format /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -2109,207 +1277,51 @@ public static void Utf8Format.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; case 12: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -2317,9 +1329,9 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -2379,222 +1399,54 @@ public static void Utf8Format.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; case 12: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); + continue; case 13: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -2602,9 +1454,9 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -2664,237 +1524,57 @@ public static void Utf8Format.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; case 12: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); + continue; case 13: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); + continue; case 14: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg15, indexParse.Alignment, writeFormat, nameof(arg15)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -2902,9 +1582,9 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -2964,252 +1652,60 @@ public static void Utf8Format.TryFormatDelegate(arg1, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg1, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg1)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + continue; case 1: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg2, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg2)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + continue; case 2: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg3, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg3)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + continue; case 3: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg4, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg4)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + continue; case 4: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg5, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg5)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + continue; case 5: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg6, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg6)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + continue; case 6: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg7, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg7)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + continue; case 7: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg8, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg8)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + continue; case 8: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg9, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg9)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + continue; case 9: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg10, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg10)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + continue; case 10: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg11, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg11)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + continue; case 11: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg12, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg12)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + continue; case 12: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg13, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg13)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg13, indexParse.Alignment, writeFormat, nameof(arg13)); + continue; case 13: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg14, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg14)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg14, indexParse.Alignment, writeFormat, nameof(arg14)); + continue; case 14: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg15, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg15)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg15, indexParse.Alignment, writeFormat, nameof(arg15)); + continue; case 15: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg16, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg16)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg16, indexParse.Alignment, writeFormat, nameof(arg16)); + continue; default: ExceptionUtil.ThrowFormatException(); break; @@ -3217,9 +1713,9 @@ public static void Utf8Format(IBufferWriter bufferWriter, T arg, int width, StandardFormat format, string argName) + { + if (width <= 0) // leftJustify + { + width *= -1; + + var buffer = bufferWriter.GetSpan(); + + if (!FormatterCache.TryFormatDelegate(arg, buffer, out var written, format)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + + if (!FormatterCache.TryFormatDelegate(arg, buffer, out written, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + bufferWriter.Advance(written); + + int padding = width - written; + if (width > 0 && padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + + ZString.AppendChars(ref bufferWriter, s.AsSpan()); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + + s.CopyTo(bufferWriter.GetSpan(charsWritten)); + bufferWriter.Advance(charsWritten); + } + } + } + } -} \ No newline at end of file +} diff --git a/src/ZString/ZString.Utf8Format.tt b/src/ZString/ZString.Utf8Format.tt index 5ca32f76..28c4129c 100644 --- a/src/ZString/ZString.Utf8Format.tt +++ b/src/ZString/ZString.Utf8Format.tt @@ -5,9 +5,11 @@ <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> <#@ include file="T4Common.t4" once="true" #> -using System.Runtime.CompilerServices; -using System.Buffers; using System; +using System.Buffers; +using System.Runtime.CompilerServices; + +using static Cysharp.Text.Utf8ValueStringBuilder; namespace Cysharp.Text { @@ -17,10 +19,16 @@ namespace Cysharp.Text /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format<<#= CreateTypeArgument(i) #>>(IBufferWriter bufferWriter, string format, <#= CreateParameters(i) #>) { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + var copyFrom = 0; for (int i = 0; i < format.Length; i++) { - if (format[i] == '{') + var c = format[i]; + if (c == '{') { // escape. if (i == format.Length - 1) @@ -47,28 +55,16 @@ namespace Cysharp.Text } // try to find range - var indexParse = FormatParser.Parse(format.AsSpan(i)); - copyFrom = i + indexParse.LastIndex + 1; - i = i + indexParse.LastIndex; + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; + i = indexParse.LastIndex - 1; var writeFormat = StandardFormat.Parse(indexParse.FormatString); switch (indexParse.Index) { <# for(var j = 0; j < i; j++) { #> case <#= j #>: - { - var buffer = bufferWriter.GetSpan(); - if (!Utf8ValueStringBuilder.FormatterCache>.TryFormatDelegate(arg<#= j +1 #>, buffer, out var written, writeFormat)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - if (!Utf8ValueStringBuilder.FormatterCache>.TryFormatDelegate(arg<#= j + 1 #>, buffer, out written, writeFormat)) - { - ExceptionUtil.ThrowArgumentException(nameof(arg<#= j + 1 #>)); - } - } - bufferWriter.Advance(written); - goto NEXT_LOOP; - } + Utf8FormatInternal(bufferWriter, arg<#= j + 1 #>, indexParse.Alignment, writeFormat, nameof(arg<#= j + 1 #>)); + continue; <# } #> default: ExceptionUtil.ThrowFormatException(); @@ -77,9 +73,9 @@ namespace Cysharp.Text ExceptionUtil.ThrowFormatException(); } - else if (format[i] == '}') + else if (c == '}') { - if (i != format.Length && format[i + 1] == '}') + if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; var buffer = bufferWriter.GetSpan(UTF8NoBom.GetMaxByteCount(size)); @@ -87,11 +83,13 @@ namespace Cysharp.Text bufferWriter.Advance(written); i = i + 1; // skip escaped '}' copyFrom = i; + continue; + } + else + { + ExceptionUtil.ThrowFormatException(); } } - - NEXT_LOOP: - continue; } { @@ -107,5 +105,77 @@ namespace Cysharp.Text } <# } #> + + static void Utf8FormatInternal(IBufferWriter bufferWriter, T arg, int width, StandardFormat format, string argName) + { + if (width <= 0) // leftJustify + { + width *= -1; + + var buffer = bufferWriter.GetSpan(); + + if (!FormatterCache.TryFormatDelegate(arg, buffer, out var written, format)) + { + bufferWriter.Advance(0); + buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); + + if (!FormatterCache.TryFormatDelegate(arg, buffer, out written, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + bufferWriter.Advance(written); + + int padding = width - written; + if (width > 0 && padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + } + else // rightJustify + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + + ZString.AppendChars(ref bufferWriter, s.AsSpan()); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + + if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) + { + ExceptionUtil.ThrowArgumentException(argName); + } + } + + int padding = width - charsWritten; + if (padding > 0) + { + // TODO Append(' ', padding); + bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. + bufferWriter.Advance(padding); + } + + s.CopyTo(bufferWriter.GetSpan(charsWritten)); + bufferWriter.Advance(charsWritten); + } + } + } + } -} \ No newline at end of file +} diff --git a/src/ZString/ZString.cs b/src/ZString/ZString.cs index 6a48bb20..aa4cb110 100644 --- a/src/ZString/ZString.cs +++ b/src/ZString/ZString.cs @@ -11,6 +11,14 @@ public static partial class ZString { static Encoding UTF8NoBom = new UTF8Encoding(false); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void AppendChars(ref TBufferWriter sb, ReadOnlySpan chars) + where TBufferWriter : System.Buffers.IBufferWriter + { + var span = sb.GetSpan(UTF8NoBom.GetMaxByteCount(chars.Length)); + sb.Advance(UTF8NoBom.GetBytes(chars, span)); + } + /// Create the Utf16 string StringBuilder. public static Utf16ValueStringBuilder CreateStringBuilder() { diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index eab6ce58..e2bfb159 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -31,6 +31,10 @@ + + TextTemplatingFileGenerator + FormatHelper.cs + TextTemplatingFileGenerator PreparedFormat.cs @@ -94,6 +98,11 @@ + + True + True + FormatHelper.tt + True True From 353fd617681885abd8a101ad6263d311746a825a Mon Sep 17 00:00:00 2001 From: udaken Date: Thu, 30 Jul 2020 01:29:00 +0900 Subject: [PATCH 092/139] Improved compatibility of PreparedFormat formatting string --- .../Assets/Scripts/ZString/FormatHelper.cs | 172 ++-- .../Assets/Scripts/ZString/PreparedFormat.cs | 864 ++++++++++-------- .../Scripts/ZString/PreparedFormatHelper.cs | 7 +- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 2 +- .../Scripts/ZString/ZString.Utf8Format.cs | 360 +++----- src/ZString/FormatHelper.cs | 172 ++-- src/ZString/FormatHelper.tt | 93 +- src/ZString/PreparedFormat.cs | 864 ++++++++++-------- src/ZString/PreparedFormat.tt | 14 +- src/ZString/PreparedFormatHelper.cs | 7 +- src/ZString/Utf8ValueStringBuilder.cs | 2 +- src/ZString/ZString.Utf8Format.cs | 360 +++----- src/ZString/ZString.Utf8Format.tt | 75 +- 13 files changed, 1517 insertions(+), 1475 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs b/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs index 5e23b582..de9846ca 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs @@ -5,19 +5,16 @@ namespace Cysharp.Text { - internal static partial class Utf16PreparedFormat + internal static partial class Utf16FormatHelper { - public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + const char sp = (char)' '; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FormatTo(ref TBufferWriter sb, T arg, int width, ReadOnlySpan format, string argName) where TBufferWriter : IBufferWriter { - const char sp = (char)' '; - var width = item.Alignment; - var format = item.FormatString.AsSpan(item.Offset, item.Count); - if (width <= 0) // leftJustify { - width *= -1; - var span = sb.GetSpan(0); if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) { @@ -30,6 +27,7 @@ public static void FormatTo(ref TBufferWriter sb, in FormatSeg } sb.Advance(argWritten); + width *= -1; int padding = width - argWritten; if (width > 0 && padding > 0) { @@ -38,64 +36,68 @@ public static void FormatTo(ref TBufferWriter sb, in FormatSeg sb.Advance(padding); } } - else // rightJustify + else { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } + FormatToRightJustify(ref sb, arg, width, format, argName); + } + } - var span = sb.GetSpan(s.Length); - s.AsSpan().CopyTo(span); - sb.Advance(s.Length); - } - else + private static void FormatToRightJustify(ref TBufferWriter sb, T arg, int width, ReadOnlySpan format, string argName) + where TBufferWriter : IBufferWriter + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) { - Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc char[s.Length * 2]; - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } + var span = sb.GetSpan(s.Length); + s.AsSpan().CopyTo(span); + sb.Advance(s.Length); + } + else + { + Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - int padding = width - charsWritten; - if (padding > 0) + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc char[s.Length * 2]; + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); + ExceptionUtil.ThrowArgumentException(argName); } + } - var span = sb.GetSpan(charsWritten); - s.CopyTo(span); - sb.Advance(charsWritten); + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); } } } - internal static partial class Utf8PreparedFormat + + internal static partial class Utf8FormatHelper { - public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + const byte sp = (byte)' '; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FormatTo(ref TBufferWriter sb, T arg, int width, StandardFormat format, string argName) where TBufferWriter : IBufferWriter { - const byte sp = (byte)' '; - var width = item.Alignment; - var format = item.StandardFormat; - if (width <= 0) // leftJustify { - width *= -1; - var span = sb.GetSpan(0); if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) { @@ -108,6 +110,7 @@ public static void FormatTo(ref TBufferWriter sb, in FormatSeg } sb.Advance(argWritten); + width *= -1; int padding = width - argWritten; if (width > 0 && padding > 0) { @@ -116,47 +119,54 @@ public static void FormatTo(ref TBufferWriter sb, in FormatSeg sb.Advance(padding); } } - else // rightJustify + else { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } + FormatToRightJustify(ref sb, arg, width, format, argName); + } + } - ZString.AppendChars(ref sb, s.AsSpan()); - } - else + private static void FormatToRightJustify(ref TBufferWriter sb, T arg, int width, StandardFormat format, string argName) + where TBufferWriter : IBufferWriter + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) { - Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc byte[s.Length * 2]; - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } + ZString.AppendChars(ref sb, s.AsSpan()); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - int padding = width - charsWritten; - if (padding > 0) + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); + ExceptionUtil.ThrowArgumentException(argName); } + } - var span = sb.GetSpan(charsWritten); - s.CopyTo(span); - sb.Advance(charsWritten); + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); } } } -} + +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs index 8d5210fa..ae9a2976 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs @@ -44,23 +44,27 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } + default: + break; } } } @@ -105,28 +109,32 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } + default: + break; } } } @@ -171,33 +179,37 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } + default: + break; } } } @@ -242,38 +254,42 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } + default: + break; } } } @@ -318,43 +334,47 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } + default: + break; } } } @@ -399,48 +419,52 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } + default: + break; } } } @@ -485,53 +509,57 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } + default: + break; } } } @@ -576,58 +604,62 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } + default: + break; } } } @@ -672,63 +704,67 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } + default: + break; } } } @@ -773,68 +809,72 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } + default: + break; } } } @@ -879,73 +919,77 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } + default: + break; } } } @@ -990,78 +1034,82 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } + default: + break; } } } @@ -1106,83 +1154,87 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } case 12: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); break; } + default: + break; } } } @@ -1227,88 +1279,92 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } case 12: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); break; } case 13: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); break; } + default: + break; } } } @@ -1353,93 +1409,97 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } case 12: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); break; } case 13: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); break; } case 14: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + Utf16FormatHelper.FormatTo(ref sb, arg15, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg15)); break; } + default: + break; } } } @@ -1484,98 +1544,102 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } case 12: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); break; } case 13: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); break; } case 14: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + Utf16FormatHelper.FormatTo(ref sb, arg15, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg15)); break; } case 15: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg16, nameof(arg16)); + Utf16FormatHelper.FormatTo(ref sb, arg16, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg16)); break; } + default: + break; } } } @@ -1620,24 +1684,28 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } + default: + break; } } } @@ -1682,29 +1750,33 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } + default: + break; } } } @@ -1749,34 +1821,38 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } + default: + break; } } } @@ -1821,39 +1897,43 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } + default: + break; } } } @@ -1898,44 +1978,48 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } + default: + break; } } } @@ -1980,49 +2064,53 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } + default: + break; } } } @@ -2067,54 +2155,58 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } + default: + break; } } } @@ -2159,59 +2251,63 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } + default: + break; } } } @@ -2256,64 +2352,68 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } + default: + break; } } } @@ -2358,69 +2458,73 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } + default: + break; } } } @@ -2465,74 +2569,78 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } + default: + break; } } } @@ -2577,79 +2685,83 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } + default: + break; } } } @@ -2694,84 +2806,88 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } case 12: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); break; } + default: + break; } } } @@ -2816,89 +2932,93 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } case 12: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); break; } case 13: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); break; } + default: + break; } } } @@ -2943,94 +3063,98 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } case 12: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); break; } case 13: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); break; } case 14: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + Utf8FormatHelper.FormatTo(ref sb, arg15, item.Alignment, item.StandardFormat, nameof(arg15)); break; } + default: + break; } } } @@ -3075,99 +3199,103 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } case 12: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); break; } case 13: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); break; } case 14: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + Utf8FormatHelper.FormatTo(ref sb, arg15, item.Alignment, item.StandardFormat, nameof(arg15)); break; } case 15: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg16, nameof(arg16)); + Utf8FormatHelper.FormatTo(ref sb, arg16, item.Alignment, item.StandardFormat, nameof(arg16)); break; } + default: + break; } } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs index 048c55d0..8178f74f 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs @@ -75,12 +75,14 @@ internal readonly struct FormatSegment { public const int NotFormatIndex = -1; + //public readonly bool IsFormatArgument; + public bool IsFormatArgument => FormatIndex != NotFormatIndex; + public readonly int Offset; public readonly int Count; - public bool IsFormatArgument => FormatIndex != NotFormatIndex; + public readonly int Alignment; public readonly int FormatIndex; public readonly string FormatString; - public readonly int Alignment; // Utf8 public readonly StandardFormat StandardFormat; @@ -89,6 +91,7 @@ public FormatSegment(int offset, int count, int formatIndex, string formatString { Offset = offset; Count = count; + //IsFormatArgument = formatIndex != NotFormatIndex; FormatIndex = formatIndex; FormatString = formatString; Alignment = alignment; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 2c4c822c..56cfce2e 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -13,7 +13,7 @@ public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter, const int ThreadStaticBufferSize = 64444; const int DefaultBufferSize = 65536; // use 64K default buffer. - internal static readonly Encoding UTF8NoBom = new UTF8Encoding(false); + static Encoding UTF8NoBom = new UTF8Encoding(false); static byte newLine1; static byte newLine2; diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs index 0756b1f6..ce267b90 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Utf8Format.cs @@ -54,7 +54,7 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -93,7 +93,6 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2) { @@ -140,10 +139,10 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -182,7 +181,6 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3) { @@ -229,13 +227,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -274,7 +272,6 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { @@ -321,16 +318,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -369,7 +366,6 @@ public static void Utf8Format(IBufferWriter bufferWriter, } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { @@ -416,19 +412,19 @@ public static void Utf8Format(IBufferWriter bufferWrit switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -467,7 +463,6 @@ public static void Utf8Format(IBufferWriter bufferWrit } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { @@ -514,22 +509,22 @@ public static void Utf8Format(IBufferWriter buffer switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -568,7 +563,6 @@ public static void Utf8Format(IBufferWriter buffer } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { @@ -615,25 +609,25 @@ public static void Utf8Format(IBufferWriter bu switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -672,7 +666,6 @@ public static void Utf8Format(IBufferWriter bu } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { @@ -719,28 +712,28 @@ public static void Utf8Format(IBufferWriter(IBufferWriterReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { @@ -826,31 +818,31 @@ public static void Utf8Format(IBufferWriter< switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -889,7 +881,6 @@ public static void Utf8Format(IBufferWriter< } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { @@ -936,34 +927,34 @@ public static void Utf8Format(IBufferWr switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -1002,7 +993,6 @@ public static void Utf8Format(IBufferWr } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { @@ -1049,37 +1039,37 @@ public static void Utf8Format(IBuf switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -1118,7 +1108,6 @@ public static void Utf8Format(IBuf } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { @@ -1165,40 +1154,40 @@ public static void Utf8Format switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; case 11: - Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -1237,7 +1226,6 @@ public static void Utf8Format } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { @@ -1284,43 +1272,43 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { @@ -1406,46 +1393,46 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { @@ -1531,49 +1517,49 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { @@ -1659,52 +1644,52 @@ public static void Utf8Format(IBufferWriter bufferWriter, T arg, int width, StandardFormat format, string argName) - { - if (width <= 0) // leftJustify - { - width *= -1; - - var buffer = bufferWriter.GetSpan(); - - if (!FormatterCache.TryFormatDelegate(arg, buffer, out var written, format)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - - if (!FormatterCache.TryFormatDelegate(arg, buffer, out written, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - - bufferWriter.Advance(written); - - int padding = width - written; - if (width > 0 && padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - } - else // rightJustify - { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - - ZString.AppendChars(ref bufferWriter, s.AsSpan()); - } - else - { - Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - - if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc byte[s.Length * 2]; - if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - - int padding = width - charsWritten; - if (padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - - s.CopyTo(bufferWriter.GetSpan(charsWritten)); - bufferWriter.Advance(charsWritten); - } - } - } - } } diff --git a/src/ZString/FormatHelper.cs b/src/ZString/FormatHelper.cs index 5e23b582..de9846ca 100644 --- a/src/ZString/FormatHelper.cs +++ b/src/ZString/FormatHelper.cs @@ -5,19 +5,16 @@ namespace Cysharp.Text { - internal static partial class Utf16PreparedFormat + internal static partial class Utf16FormatHelper { - public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + const char sp = (char)' '; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FormatTo(ref TBufferWriter sb, T arg, int width, ReadOnlySpan format, string argName) where TBufferWriter : IBufferWriter { - const char sp = (char)' '; - var width = item.Alignment; - var format = item.FormatString.AsSpan(item.Offset, item.Count); - if (width <= 0) // leftJustify { - width *= -1; - var span = sb.GetSpan(0); if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) { @@ -30,6 +27,7 @@ public static void FormatTo(ref TBufferWriter sb, in FormatSeg } sb.Advance(argWritten); + width *= -1; int padding = width - argWritten; if (width > 0 && padding > 0) { @@ -38,64 +36,68 @@ public static void FormatTo(ref TBufferWriter sb, in FormatSeg sb.Advance(padding); } } - else // rightJustify + else { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } + FormatToRightJustify(ref sb, arg, width, format, argName); + } + } - var span = sb.GetSpan(s.Length); - s.AsSpan().CopyTo(span); - sb.Advance(s.Length); - } - else + private static void FormatToRightJustify(ref TBufferWriter sb, T arg, int width, ReadOnlySpan format, string argName) + where TBufferWriter : IBufferWriter + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) { - Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc char[s.Length * 2]; - if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } + var span = sb.GetSpan(s.Length); + s.AsSpan().CopyTo(span); + sb.Advance(s.Length); + } + else + { + Span s = stackalloc char[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - int padding = width - charsWritten; - if (padding > 0) + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc char[s.Length * 2]; + if (!Utf16ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); + ExceptionUtil.ThrowArgumentException(argName); } + } - var span = sb.GetSpan(charsWritten); - s.CopyTo(span); - sb.Advance(charsWritten); + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); } } } - internal static partial class Utf8PreparedFormat + + internal static partial class Utf8FormatHelper { - public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + const byte sp = (byte)' '; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FormatTo(ref TBufferWriter sb, T arg, int width, StandardFormat format, string argName) where TBufferWriter : IBufferWriter { - const byte sp = (byte)' '; - var width = item.Alignment; - var format = item.StandardFormat; - if (width <= 0) // leftJustify { - width *= -1; - var span = sb.GetSpan(0); if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) { @@ -108,6 +110,7 @@ public static void FormatTo(ref TBufferWriter sb, in FormatSeg } sb.Advance(argWritten); + width *= -1; int padding = width - argWritten; if (width > 0 && padding > 0) { @@ -116,47 +119,54 @@ public static void FormatTo(ref TBufferWriter sb, in FormatSeg sb.Advance(padding); } } - else // rightJustify + else { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } + FormatToRightJustify(ref sb, arg, width, format, argName); + } + } - ZString.AppendChars(ref sb, s.AsSpan()); - } - else + private static void FormatToRightJustify(ref TBufferWriter sb, T arg, int width, StandardFormat format, string argName) + where TBufferWriter : IBufferWriter + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) { - Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc byte[s.Length * 2]; - if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } + ZString.AppendChars(ref sb, s.AsSpan()); + } + else + { + Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - int padding = width - charsWritten; - if (padding > 0) + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc byte[s.Length * 2]; + if (!Utf8ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); + ExceptionUtil.ThrowArgumentException(argName); } + } - var span = sb.GetSpan(charsWritten); - s.CopyTo(span); - sb.Advance(charsWritten); + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); } } } -} + +} \ No newline at end of file diff --git a/src/ZString/FormatHelper.tt b/src/ZString/FormatHelper.tt index db3f1c89..d6ed5aa3 100644 --- a/src/ZString/FormatHelper.tt +++ b/src/ZString/FormatHelper.tt @@ -13,19 +13,16 @@ using System.Runtime.CompilerServices; namespace Cysharp.Text { <# foreach(var utf in utfTypes ) { var isUtf16 = (utf == "Utf16"); var elemType = isUtf16 ? "char" : "byte"; #> - internal static partial class <#= utf #>PreparedFormat + internal static partial class <#= utf #>FormatHelper { - public static void FormatTo(ref TBufferWriter sb, in FormatSegment item, T arg, string argName) + const <#= elemType #> sp = (<#= elemType #>)' '; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FormatTo(ref TBufferWriter sb, T arg, int width, <#= isUtf16 ? "ReadOnlySpan" : "StandardFormat" #> format, string argName) where TBufferWriter : IBufferWriter<<#= elemType #>> { - const <#= elemType #> sp = (<#= elemType #>)' '; - var width = item.Alignment; - var format = <#= isUtf16 ? "item.FormatString.AsSpan(item.Offset, item.Count)" : "item.StandardFormat" #>; - if (width <= 0) // leftJustify { - width *= -1; - var span = sb.GetSpan(0); if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, span, out var argWritten, format)) { @@ -38,6 +35,7 @@ namespace Cysharp.Text } sb.Advance(argWritten); + width *= -1; int padding = width - argWritten; if (width > 0 && padding > 0) { @@ -46,54 +44,61 @@ namespace Cysharp.Text sb.Advance(padding); } } - else // rightJustify + else { - if (typeof(T) == typeof(string)) + FormatToRightJustify(ref sb, arg, width, format, argName); + } + } + + private static void FormatToRightJustify(ref TBufferWriter sb, T arg, int width, <#= isUtf16 ? "ReadOnlySpan" : "StandardFormat" #> format, string argName) + where TBufferWriter : IBufferWriter<<#= elemType #>> + { + if (typeof(T) == typeof(string)) + { + var s = Unsafe.As(arg); + int padding = width - s.Length; + if (padding > 0) { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); - } + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); + } <# if(isUtf16) { #> - var span = sb.GetSpan(s.Length); - s.AsSpan().CopyTo(span); - sb.Advance(s.Length); + var span = sb.GetSpan(s.Length); + s.AsSpan().CopyTo(span); + sb.Advance(s.Length); <# }else { #> - ZString.AppendChars(ref sb, s.AsSpan()); + ZString.AppendChars(ref sb, s.AsSpan()); <# } #> - } - else - { - Span<<#= elemType #>> s = stackalloc <#= elemType #>[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - - if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc <#= elemType #>[s.Length * 2]; - if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } + } + else + { + Span<<#= elemType #>> s = stackalloc <#= elemType #>[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - int padding = width - charsWritten; - if (padding > 0) + if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) + { + s = stackalloc <#= elemType #>[s.Length * 2]; + if (!<#= utf #>ValueStringBuilder.FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) { - var paddingSpan = sb.GetSpan(padding); - paddingSpan.Fill(sp); - sb.Advance(padding); + ExceptionUtil.ThrowArgumentException(argName); } + } - var span = sb.GetSpan(charsWritten); - s.CopyTo(span); - sb.Advance(charsWritten); + int padding = width - charsWritten; + if (padding > 0) + { + var paddingSpan = sb.GetSpan(padding); + paddingSpan.Fill(sp); + sb.Advance(padding); } + + var span = sb.GetSpan(charsWritten); + s.CopyTo(span); + sb.Advance(charsWritten); } } } + <# } // foreach(utf) #> -} +} \ No newline at end of file diff --git a/src/ZString/PreparedFormat.cs b/src/ZString/PreparedFormat.cs index 8d5210fa..ae9a2976 100644 --- a/src/ZString/PreparedFormat.cs +++ b/src/ZString/PreparedFormat.cs @@ -44,23 +44,27 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } + default: + break; } } } @@ -105,28 +109,32 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } + default: + break; } } } @@ -171,33 +179,37 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } + default: + break; } } } @@ -242,38 +254,42 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } + default: + break; } } } @@ -318,43 +334,47 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } + default: + break; } } } @@ -399,48 +419,52 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } + default: + break; } } } @@ -485,53 +509,57 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } + default: + break; } } } @@ -576,58 +604,62 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } + default: + break; } } } @@ -672,63 +704,67 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } + default: + break; } } } @@ -773,68 +809,72 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } + default: + break; } } } @@ -879,73 +919,77 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } + default: + break; } } } @@ -990,78 +1034,82 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } + default: + break; } } } @@ -1106,83 +1154,87 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } case 12: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); break; } + default: + break; } } } @@ -1227,88 +1279,92 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } case 12: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); break; } case 13: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); break; } + default: + break; } } } @@ -1353,93 +1409,97 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } case 12: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); break; } case 13: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); break; } case 14: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + Utf16FormatHelper.FormatTo(ref sb, arg15, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg15)); break; } + default: + break; } } } @@ -1484,98 +1544,102 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); + break; } - break; case 0: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf16FormatHelper.FormatTo(ref sb, arg1, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg1)); break; } case 1: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf16FormatHelper.FormatTo(ref sb, arg2, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg2)); break; } case 2: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf16FormatHelper.FormatTo(ref sb, arg3, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg3)); break; } case 3: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf16FormatHelper.FormatTo(ref sb, arg4, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg4)); break; } case 4: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf16FormatHelper.FormatTo(ref sb, arg5, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg5)); break; } case 5: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf16FormatHelper.FormatTo(ref sb, arg6, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg6)); break; } case 6: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf16FormatHelper.FormatTo(ref sb, arg7, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg7)); break; } case 7: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf16FormatHelper.FormatTo(ref sb, arg8, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg8)); break; } case 8: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf16FormatHelper.FormatTo(ref sb, arg9, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg9)); break; } case 9: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf16FormatHelper.FormatTo(ref sb, arg10, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg10)); break; } case 10: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf16FormatHelper.FormatTo(ref sb, arg11, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg11)); break; } case 11: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf16FormatHelper.FormatTo(ref sb, arg12, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg12)); break; } case 12: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf16FormatHelper.FormatTo(ref sb, arg13, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg13)); break; } case 13: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf16FormatHelper.FormatTo(ref sb, arg14, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg14)); break; } case 14: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + Utf16FormatHelper.FormatTo(ref sb, arg15, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg15)); break; } case 15: { - Utf16PreparedFormat.FormatTo(ref sb, item, arg16, nameof(arg16)); + Utf16FormatHelper.FormatTo(ref sb, arg16, item.Alignment, formatSpan.Slice(item.Offset, item.Count), nameof(arg16)); break; } + default: + break; } } } @@ -1620,24 +1684,28 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } + default: + break; } } } @@ -1682,29 +1750,33 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } + default: + break; } } } @@ -1749,34 +1821,38 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } + default: + break; } } } @@ -1821,39 +1897,43 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } + default: + break; } } } @@ -1898,44 +1978,48 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } + default: + break; } } } @@ -1980,49 +2064,53 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } + default: + break; } } } @@ -2067,54 +2155,58 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } + default: + break; } } } @@ -2159,59 +2251,63 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } + default: + break; } } } @@ -2256,64 +2352,68 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } + default: + break; } } } @@ -2358,69 +2458,73 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } + default: + break; } } } @@ -2465,74 +2569,78 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } + default: + break; } } } @@ -2577,79 +2685,83 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } + default: + break; } } } @@ -2694,84 +2806,88 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } case 12: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); break; } + default: + break; } } } @@ -2816,89 +2932,93 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } case 12: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); break; } case 13: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); break; } + default: + break; } } } @@ -2943,94 +3063,98 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } case 12: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); break; } case 13: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); break; } case 14: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + Utf8FormatHelper.FormatTo(ref sb, arg15, item.Alignment, item.StandardFormat, nameof(arg15)); break; } + default: + break; } } } @@ -3075,99 +3199,103 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); + break; } - break; case 0: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg1, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref sb, arg1, item.Alignment, item.StandardFormat, nameof(arg1)); break; } case 1: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg2, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref sb, arg2, item.Alignment, item.StandardFormat, nameof(arg2)); break; } case 2: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg3, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref sb, arg3, item.Alignment, item.StandardFormat, nameof(arg3)); break; } case 3: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg4, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref sb, arg4, item.Alignment, item.StandardFormat, nameof(arg4)); break; } case 4: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg5, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref sb, arg5, item.Alignment, item.StandardFormat, nameof(arg5)); break; } case 5: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg6, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref sb, arg6, item.Alignment, item.StandardFormat, nameof(arg6)); break; } case 6: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg7, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref sb, arg7, item.Alignment, item.StandardFormat, nameof(arg7)); break; } case 7: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg8, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref sb, arg8, item.Alignment, item.StandardFormat, nameof(arg8)); break; } case 8: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg9, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref sb, arg9, item.Alignment, item.StandardFormat, nameof(arg9)); break; } case 9: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg10, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref sb, arg10, item.Alignment, item.StandardFormat, nameof(arg10)); break; } case 10: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg11, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref sb, arg11, item.Alignment, item.StandardFormat, nameof(arg11)); break; } case 11: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg12, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref sb, arg12, item.Alignment, item.StandardFormat, nameof(arg12)); break; } case 12: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg13, nameof(arg13)); + Utf8FormatHelper.FormatTo(ref sb, arg13, item.Alignment, item.StandardFormat, nameof(arg13)); break; } case 13: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg14, nameof(arg14)); + Utf8FormatHelper.FormatTo(ref sb, arg14, item.Alignment, item.StandardFormat, nameof(arg14)); break; } case 14: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg15, nameof(arg15)); + Utf8FormatHelper.FormatTo(ref sb, arg15, item.Alignment, item.StandardFormat, nameof(arg15)); break; } case 15: { - Utf8PreparedFormat.FormatTo(ref sb, item, arg16, nameof(arg16)); + Utf8FormatHelper.FormatTo(ref sb, arg16, item.Alignment, item.StandardFormat, nameof(arg16)); break; } + default: + break; } } } diff --git a/src/ZString/PreparedFormat.tt b/src/ZString/PreparedFormat.tt index b34f0ccb..81af478f 100644 --- a/src/ZString/PreparedFormat.tt +++ b/src/ZString/PreparedFormat.tt @@ -53,32 +53,36 @@ namespace Cysharp.Text public void FormatTo(ref TBufferWriter sb, <#= CreateParameters(i) #>) where TBufferWriter : IBufferWriter<<#= isUtf16 ? "char" : "byte" #>> { + var formatSpan = FormatString.AsSpan(); + foreach (var item in segments) { switch (item.FormatIndex) { case FormatSegment.NotFormatIndex: { - var strSpan = FormatString.AsSpan(item.Offset, item.Count); + var strSpan = formatSpan.Slice(item.Offset, item.Count); <# if(isUtf16) { #> var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); <# } else { #> - var size = Utf8ValueStringBuilder.UTF8NoBom.GetMaxByteCount(item.Count); + var size = Encoding.UTF8.GetMaxByteCount(item.Count); var span = sb.GetSpan(size); - var count = Utf8ValueStringBuilder.UTF8NoBom.GetBytes(strSpan, span); + var count = Encoding.UTF8.GetBytes(strSpan, span); sb.Advance(count); <# } #> + break; } - break; <# for(var j = 0; j < i; j++) { #> case <#= j #>: { - <#= utf #>PreparedFormat.FormatTo(ref sb, item, arg<#= j + 1 #>, nameof(arg<#= j + 1 #>)); + <#= utf #>FormatHelper.FormatTo(ref sb, arg<#= j + 1 #>, item.Alignment, <#= isUtf16 ? "formatSpan.Slice(item.Offset, item.Count)" : "item.StandardFormat" #>, nameof(arg<#= j + 1 #>)); break; } <# } // for(j) #> + default: + break; } } } diff --git a/src/ZString/PreparedFormatHelper.cs b/src/ZString/PreparedFormatHelper.cs index 048c55d0..8178f74f 100644 --- a/src/ZString/PreparedFormatHelper.cs +++ b/src/ZString/PreparedFormatHelper.cs @@ -75,12 +75,14 @@ internal readonly struct FormatSegment { public const int NotFormatIndex = -1; + //public readonly bool IsFormatArgument; + public bool IsFormatArgument => FormatIndex != NotFormatIndex; + public readonly int Offset; public readonly int Count; - public bool IsFormatArgument => FormatIndex != NotFormatIndex; + public readonly int Alignment; public readonly int FormatIndex; public readonly string FormatString; - public readonly int Alignment; // Utf8 public readonly StandardFormat StandardFormat; @@ -89,6 +91,7 @@ public FormatSegment(int offset, int count, int formatIndex, string formatString { Offset = offset; Count = count; + //IsFormatArgument = formatIndex != NotFormatIndex; FormatIndex = formatIndex; FormatString = formatString; Alignment = alignment; diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 2c4c822c..56cfce2e 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -13,7 +13,7 @@ public partial struct Utf8ValueStringBuilder : IDisposable, IBufferWriter, const int ThreadStaticBufferSize = 64444; const int DefaultBufferSize = 65536; // use 64K default buffer. - internal static readonly Encoding UTF8NoBom = new UTF8Encoding(false); + static Encoding UTF8NoBom = new UTF8Encoding(false); static byte newLine1; static byte newLine2; diff --git a/src/ZString/ZString.Utf8Format.cs b/src/ZString/ZString.Utf8Format.cs index 0756b1f6..ce267b90 100644 --- a/src/ZString/ZString.Utf8Format.cs +++ b/src/ZString/ZString.Utf8Format.cs @@ -54,7 +54,7 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -93,7 +93,6 @@ public static void Utf8Format(IBufferWriter bufferWriter, string forma } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2) { @@ -140,10 +139,10 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -182,7 +181,6 @@ public static void Utf8Format(IBufferWriter bufferWriter, string f } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3) { @@ -229,13 +227,13 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -274,7 +272,6 @@ public static void Utf8Format(IBufferWriter bufferWriter, stri } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { @@ -321,16 +318,16 @@ public static void Utf8Format(IBufferWriter bufferWriter, switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -369,7 +366,6 @@ public static void Utf8Format(IBufferWriter bufferWriter, } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { @@ -416,19 +412,19 @@ public static void Utf8Format(IBufferWriter bufferWrit switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -467,7 +463,6 @@ public static void Utf8Format(IBufferWriter bufferWrit } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) { @@ -514,22 +509,22 @@ public static void Utf8Format(IBufferWriter buffer switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -568,7 +563,6 @@ public static void Utf8Format(IBufferWriter buffer } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) { @@ -615,25 +609,25 @@ public static void Utf8Format(IBufferWriter bu switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -672,7 +666,6 @@ public static void Utf8Format(IBufferWriter bu } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) { @@ -719,28 +712,28 @@ public static void Utf8Format(IBufferWriter(IBufferWriterReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) { @@ -826,31 +818,31 @@ public static void Utf8Format(IBufferWriter< switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -889,7 +881,6 @@ public static void Utf8Format(IBufferWriter< } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) { @@ -936,34 +927,34 @@ public static void Utf8Format(IBufferWr switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -1002,7 +993,6 @@ public static void Utf8Format(IBufferWr } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) { @@ -1049,37 +1039,37 @@ public static void Utf8Format(IBuf switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -1118,7 +1108,6 @@ public static void Utf8Format(IBuf } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) { @@ -1165,40 +1154,40 @@ public static void Utf8Format switch (indexParse.Index) { case 0: - Utf8FormatInternal(bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg1, indexParse.Alignment, writeFormat, nameof(arg1)); continue; case 1: - Utf8FormatInternal(bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg2, indexParse.Alignment, writeFormat, nameof(arg2)); continue; case 2: - Utf8FormatInternal(bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg3, indexParse.Alignment, writeFormat, nameof(arg3)); continue; case 3: - Utf8FormatInternal(bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg4, indexParse.Alignment, writeFormat, nameof(arg4)); continue; case 4: - Utf8FormatInternal(bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg5, indexParse.Alignment, writeFormat, nameof(arg5)); continue; case 5: - Utf8FormatInternal(bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg6, indexParse.Alignment, writeFormat, nameof(arg6)); continue; case 6: - Utf8FormatInternal(bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg7, indexParse.Alignment, writeFormat, nameof(arg7)); continue; case 7: - Utf8FormatInternal(bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg8, indexParse.Alignment, writeFormat, nameof(arg8)); continue; case 8: - Utf8FormatInternal(bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg9, indexParse.Alignment, writeFormat, nameof(arg9)); continue; case 9: - Utf8FormatInternal(bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg10, indexParse.Alignment, writeFormat, nameof(arg10)); continue; case 10: - Utf8FormatInternal(bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg11, indexParse.Alignment, writeFormat, nameof(arg11)); continue; case 11: - Utf8FormatInternal(bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg12, indexParse.Alignment, writeFormat, nameof(arg12)); continue; default: ExceptionUtil.ThrowFormatException(); @@ -1237,7 +1226,6 @@ public static void Utf8Format } } } - /// Replaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) { @@ -1284,43 +1272,43 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) { @@ -1406,46 +1393,46 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) { @@ -1531,49 +1517,49 @@ public static void Utf8FormatReplaces one or more format items in a string with the string representation of some specified values. public static void Utf8Format(IBufferWriter bufferWriter, string format, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) { @@ -1659,52 +1644,52 @@ public static void Utf8Format(IBufferWriter bufferWriter, T arg, int width, StandardFormat format, string argName) - { - if (width <= 0) // leftJustify - { - width *= -1; - - var buffer = bufferWriter.GetSpan(); - - if (!FormatterCache.TryFormatDelegate(arg, buffer, out var written, format)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - - if (!FormatterCache.TryFormatDelegate(arg, buffer, out written, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - - bufferWriter.Advance(written); - - int padding = width - written; - if (width > 0 && padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - } - else // rightJustify - { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - - ZString.AppendChars(ref bufferWriter, s.AsSpan()); - } - else - { - Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - - if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc byte[s.Length * 2]; - if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - - int padding = width - charsWritten; - if (padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - - s.CopyTo(bufferWriter.GetSpan(charsWritten)); - bufferWriter.Advance(charsWritten); - } - } - } - } } diff --git a/src/ZString/ZString.Utf8Format.tt b/src/ZString/ZString.Utf8Format.tt index 28c4129c..4382e5c8 100644 --- a/src/ZString/ZString.Utf8Format.tt +++ b/src/ZString/ZString.Utf8Format.tt @@ -63,7 +63,7 @@ namespace Cysharp.Text { <# for(var j = 0; j < i; j++) { #> case <#= j #>: - Utf8FormatInternal(bufferWriter, arg<#= j + 1 #>, indexParse.Alignment, writeFormat, nameof(arg<#= j + 1 #>)); + Utf8FormatHelper.FormatTo(ref bufferWriter, arg<#= j + 1 #>, indexParse.Alignment, writeFormat, nameof(arg<#= j + 1 #>)); continue; <# } #> default: @@ -103,79 +103,6 @@ namespace Cysharp.Text } } } - <# } #> - - static void Utf8FormatInternal(IBufferWriter bufferWriter, T arg, int width, StandardFormat format, string argName) - { - if (width <= 0) // leftJustify - { - width *= -1; - - var buffer = bufferWriter.GetSpan(); - - if (!FormatterCache.TryFormatDelegate(arg, buffer, out var written, format)) - { - bufferWriter.Advance(0); - buffer = bufferWriter.GetSpan(Math.Max(buffer.Length + 1, written)); - - if (!FormatterCache.TryFormatDelegate(arg, buffer, out written, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - - bufferWriter.Advance(written); - - int padding = width - written; - if (width > 0 && padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - } - else // rightJustify - { - if (typeof(T) == typeof(string)) - { - var s = Unsafe.As(arg); - int padding = width - s.Length; - if (padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - - ZString.AppendChars(ref bufferWriter, s.AsSpan()); - } - else - { - Span s = stackalloc byte[typeof(T).IsValueType ? Unsafe.SizeOf() * 8 : 1024]; - - if (!FormatterCache.TryFormatDelegate(arg, s, out var charsWritten, format)) - { - s = stackalloc byte[s.Length * 2]; - if (!FormatterCache.TryFormatDelegate(arg, s, out charsWritten, format)) - { - ExceptionUtil.ThrowArgumentException(argName); - } - } - - int padding = width - charsWritten; - if (padding > 0) - { - // TODO Append(' ', padding); - bufferWriter.GetSpan(padding).Fill((byte)' '); // TODO Fill Method is too slow. - bufferWriter.Advance(padding); - } - - s.CopyTo(bufferWriter.GetSpan(charsWritten)); - bufferWriter.Advance(charsWritten); - } - } - } - } } From f790e99555efa4c6572945011e8d4b8b3dfc8fed Mon Sep 17 00:00:00 2001 From: udaken Date: Thu, 6 Aug 2020 21:41:31 +0900 Subject: [PATCH 093/139] Optimize PreparedFormat --- .../Assets/Scripts/ZString/PreparedFormat.cs | 352 +++++++++--------- .../Scripts/ZString/PreparedFormatHelper.cs | 115 ++++-- src/ZString/PreparedFormat.cs | 352 +++++++++--------- src/ZString/PreparedFormat.tt | 20 +- src/ZString/PreparedFormatHelper.cs | 115 ++++-- 5 files changed, 548 insertions(+), 406 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs index ae9a2976..955c5ca6 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormat.cs @@ -9,12 +9,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -50,7 +50,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -74,12 +74,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -115,7 +115,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -144,12 +144,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -185,7 +185,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -219,12 +219,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -260,7 +260,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -299,12 +299,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -340,7 +340,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -384,12 +384,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -425,7 +425,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -474,12 +474,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -515,7 +515,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -569,12 +569,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -610,7 +610,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -669,12 +669,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -774,12 +774,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -884,12 +884,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -999,12 +999,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1119,12 +1119,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1244,12 +1244,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1374,12 +1374,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1509,12 +1509,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1649,12 +1649,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1684,19 +1685,18 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -1715,12 +1715,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1750,19 +1751,18 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -1786,12 +1786,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1821,19 +1822,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -1862,12 +1862,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1897,19 +1898,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -1943,12 +1943,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1978,19 +1979,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2029,12 +2029,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -2064,19 +2065,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2120,12 +2120,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -2155,19 +2156,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2216,12 +2216,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -2251,19 +2252,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2317,12 +2317,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2423,12 +2423,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2534,12 +2534,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2650,12 +2650,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2771,12 +2771,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2897,12 +2897,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -3028,12 +3028,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -3164,12 +3164,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs index 8178f74f..18d808da 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/PreparedFormatHelper.cs @@ -1,20 +1,20 @@ using System; using System.Buffers; using System.Collections.Generic; -using System.Diagnostics; +using System.Text; namespace Cysharp.Text { internal static class PreparedFormatHelper { - internal static FormatSegment[] Parse(string format, bool withStandardFormat) + internal static Utf16FormatSegment[] Utf16Parse(string format) { if (format == null) { throw new ArgumentNullException(nameof(format)); } - var list = new List(); + var list = new List(); int i = 0; int len = format.Length; @@ -42,7 +42,7 @@ internal static FormatSegment[] Parse(string format, bool withStandardFormat) if (size != 0) { - list.Add(new FormatSegment(copyFrom, size, FormatSegment.NotFormatIndex, format, default, 0)); + list.Add(new Utf16FormatSegment(copyFrom, size, Utf16FormatSegment.NotFormatIndex, 0)); } copyFrom = i; @@ -63,46 +63,117 @@ internal static FormatSegment[] Parse(string format, bool withStandardFormat) copyFrom = indexParse.LastIndex; // continue after '}' i = indexParse.LastIndex; - list.Add(new FormatSegment(indexParse.LastIndex - indexParse.FormatString.Length - 1, indexParse.FormatString.Length, indexParse.Index, format, withStandardFormat, indexParse.Alignment)); + list.Add(new Utf16FormatSegment(indexParse.LastIndex - indexParse.FormatString.Length - 1, indexParse.FormatString.Length, indexParse.Index, indexParse.Alignment)); + } + + return list.ToArray(); + } + internal static Utf8FormatSegment[] Utf8Parse(string format, out byte[] utf8buffer) + { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + + var list = new List(); + utf8buffer = new byte[Encoding.UTF8.GetMaxByteCount(format.Length)]; + var bufOffset = 0; + + int i = 0; + int len = format.Length; + + var copyFrom = 0; + var formatSpan = format.AsSpan(); + + while (true) + { + while (i < len) + { + var parserScanResult = FormatParser.ScanFormatString(formatSpan, ref i); + + if (ParserScanResult.NormalChar == parserScanResult && i < len) + { + // skip normal char + continue; + } + + var size = i - copyFrom; + if (ParserScanResult.EscapedChar == parserScanResult) + { + size--; + } + + if (size != 0) + { + var utf8size = Encoding.UTF8.GetBytes(format, copyFrom, size, utf8buffer, bufOffset); + list.Add(new Utf8FormatSegment(bufOffset, utf8size, Utf8FormatSegment.NotFormatIndex, default, 0)); + bufOffset += utf8size; + } + + copyFrom = i; + + if (ParserScanResult.BraceOpen == parserScanResult) + { + break; + } + } + + if (i >= len) + { + break; + } + + // Here it is before `{`. + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; // continue after '}' + i = indexParse.LastIndex; + list.Add(new Utf8FormatSegment(0, 0, indexParse.Index, StandardFormat.Parse(indexParse.FormatString), indexParse.Alignment)); } return list.ToArray(); } } - internal readonly struct FormatSegment + internal readonly struct Utf8FormatSegment { public const int NotFormatIndex = -1; - //public readonly bool IsFormatArgument; + public readonly int Offset; + public readonly int Count; + public readonly int FormatIndex; + public readonly StandardFormat StandardFormat; + public readonly int Alignment; + public bool IsFormatArgument => FormatIndex != NotFormatIndex; + public Utf8FormatSegment(int offset, int count, int formatIndex, StandardFormat format, int alignment) + { + Offset = offset; + Count = count; + FormatIndex = formatIndex; + StandardFormat = format; + Alignment = alignment; + } + } + + internal readonly struct Utf16FormatSegment + { + public const int NotFormatIndex = -1; + public readonly int Offset; public readonly int Count; - public readonly int Alignment; public readonly int FormatIndex; - public readonly string FormatString; + public readonly int Alignment; - // Utf8 - public readonly StandardFormat StandardFormat; + public bool IsFormatArgument => FormatIndex != NotFormatIndex; - public FormatSegment(int offset, int count, int formatIndex, string formatString, bool utf8, int alignment) + public Utf16FormatSegment(int offset, int count, int formatIndex, int alignment) { Offset = offset; Count = count; - //IsFormatArgument = formatIndex != NotFormatIndex; FormatIndex = formatIndex; - FormatString = formatString; Alignment = alignment; - if (utf8) - { - StandardFormat = (formatString != null) ? StandardFormat.Parse(formatString.AsSpan(Offset, Count)) : default; - } - else - { - StandardFormat = default; - } } } } diff --git a/src/ZString/PreparedFormat.cs b/src/ZString/PreparedFormat.cs index ae9a2976..955c5ca6 100644 --- a/src/ZString/PreparedFormat.cs +++ b/src/ZString/PreparedFormat.cs @@ -9,12 +9,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -50,7 +50,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -74,12 +74,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -115,7 +115,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -144,12 +144,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -185,7 +185,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -219,12 +219,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -260,7 +260,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -299,12 +299,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -340,7 +340,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -384,12 +384,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -425,7 +425,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -474,12 +474,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -515,7 +515,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -569,12 +569,12 @@ public sealed partial class Utf16PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf16FormatSegment[] segments; public Utf16PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, false); + this.segments = PreparedFormatHelper.Utf16Parse(format); var size = 0; foreach (var item in segments) @@ -610,7 +610,7 @@ public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -669,12 +669,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -774,12 +774,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -884,12 +884,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -999,12 +999,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1119,12 +1119,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1244,12 +1244,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1374,12 +1374,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1509,12 +1509,12 @@ public sealed partial class Utf16PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 a { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf16FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); var span = sb.GetSpan(item.Count); @@ -1649,12 +1649,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1684,19 +1685,18 @@ public string Format(T1 arg1) public void FormatTo(ref TBufferWriter sb, T1 arg1) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -1715,12 +1715,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1750,19 +1751,18 @@ public string Format(T1 arg1, T2 arg2) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -1786,12 +1786,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1821,19 +1822,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -1862,12 +1862,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1897,19 +1898,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -1943,12 +1943,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -1978,19 +1979,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2029,12 +2029,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -2064,19 +2065,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2120,12 +2120,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -2155,19 +2156,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2216,12 +2216,13 @@ public sealed partial class Utf8PreparedFormat public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly Utf8FormatSegment[] segments; + readonly byte[] utf8PreEncodedbuffer; public Utf8PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, true); + this.segments = PreparedFormatHelper.Utf8Parse(format, out utf8PreEncodedbuffer); var size = 0; foreach (var item in segments) @@ -2251,19 +2252,18 @@ public string Format(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 ar public void FormatTo(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2317,12 +2317,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2423,12 +2423,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2534,12 +2534,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2650,12 +2650,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2771,12 +2771,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -2897,12 +2897,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -3028,12 +3028,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: @@ -3164,12 +3164,13 @@ public sealed partial class Utf8PreparedFormat(ref TBufferWriter sb, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16) where TBufferWriter : IBufferWriter { - var formatSpan = FormatString.AsSpan(); + var formatSpan = utf8PreEncodedbuffer.AsSpan(); foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case Utf8FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); + var span = sb.GetSpan(item.Count); + strSpan.TryCopyTo(span); + sb.Advance(item.Count); break; } case 0: diff --git a/src/ZString/PreparedFormat.tt b/src/ZString/PreparedFormat.tt index 81af478f..19f724aa 100644 --- a/src/ZString/PreparedFormat.tt +++ b/src/ZString/PreparedFormat.tt @@ -18,12 +18,15 @@ namespace Cysharp.Text public string FormatString { get; } public int MinSize { get; } - readonly FormatSegment[] segments; + readonly <#= utf #>FormatSegment[] segments; +<# if(!isUtf16) { #> + readonly byte[] utf8PreEncodedbuffer; +<# } #> public <#= utf #>PreparedFormat(string format) { this.FormatString = format; - this.segments = PreparedFormatHelper.Parse(format, <#= (utf == "Utf16" ? false : true).ToString().ToLower() #>); + this.segments = PreparedFormatHelper.<#= utf #>Parse(format<#= (!isUtf16 ? ", out utf8PreEncodedbuffer" : "") #>); var size = 0; foreach (var item in segments) @@ -53,25 +56,22 @@ namespace Cysharp.Text public void FormatTo(ref TBufferWriter sb, <#= CreateParameters(i) #>) where TBufferWriter : IBufferWriter<<#= isUtf16 ? "char" : "byte" #>> { +<# if(isUtf16) { #> var formatSpan = FormatString.AsSpan(); +<# } else { #> + var formatSpan = utf8PreEncodedbuffer.AsSpan(); +<# } #> foreach (var item in segments) { switch (item.FormatIndex) { - case FormatSegment.NotFormatIndex: + case <#= utf #>FormatSegment.NotFormatIndex: { var strSpan = formatSpan.Slice(item.Offset, item.Count); -<# if(isUtf16) { #> var span = sb.GetSpan(item.Count); strSpan.TryCopyTo(span); sb.Advance(item.Count); -<# } else { #> - var size = Encoding.UTF8.GetMaxByteCount(item.Count); - var span = sb.GetSpan(size); - var count = Encoding.UTF8.GetBytes(strSpan, span); - sb.Advance(count); -<# } #> break; } <# for(var j = 0; j < i; j++) { #> diff --git a/src/ZString/PreparedFormatHelper.cs b/src/ZString/PreparedFormatHelper.cs index 8178f74f..18d808da 100644 --- a/src/ZString/PreparedFormatHelper.cs +++ b/src/ZString/PreparedFormatHelper.cs @@ -1,20 +1,20 @@ using System; using System.Buffers; using System.Collections.Generic; -using System.Diagnostics; +using System.Text; namespace Cysharp.Text { internal static class PreparedFormatHelper { - internal static FormatSegment[] Parse(string format, bool withStandardFormat) + internal static Utf16FormatSegment[] Utf16Parse(string format) { if (format == null) { throw new ArgumentNullException(nameof(format)); } - var list = new List(); + var list = new List(); int i = 0; int len = format.Length; @@ -42,7 +42,7 @@ internal static FormatSegment[] Parse(string format, bool withStandardFormat) if (size != 0) { - list.Add(new FormatSegment(copyFrom, size, FormatSegment.NotFormatIndex, format, default, 0)); + list.Add(new Utf16FormatSegment(copyFrom, size, Utf16FormatSegment.NotFormatIndex, 0)); } copyFrom = i; @@ -63,46 +63,117 @@ internal static FormatSegment[] Parse(string format, bool withStandardFormat) copyFrom = indexParse.LastIndex; // continue after '}' i = indexParse.LastIndex; - list.Add(new FormatSegment(indexParse.LastIndex - indexParse.FormatString.Length - 1, indexParse.FormatString.Length, indexParse.Index, format, withStandardFormat, indexParse.Alignment)); + list.Add(new Utf16FormatSegment(indexParse.LastIndex - indexParse.FormatString.Length - 1, indexParse.FormatString.Length, indexParse.Index, indexParse.Alignment)); + } + + return list.ToArray(); + } + internal static Utf8FormatSegment[] Utf8Parse(string format, out byte[] utf8buffer) + { + if (format == null) + { + throw new ArgumentNullException(nameof(format)); + } + + var list = new List(); + utf8buffer = new byte[Encoding.UTF8.GetMaxByteCount(format.Length)]; + var bufOffset = 0; + + int i = 0; + int len = format.Length; + + var copyFrom = 0; + var formatSpan = format.AsSpan(); + + while (true) + { + while (i < len) + { + var parserScanResult = FormatParser.ScanFormatString(formatSpan, ref i); + + if (ParserScanResult.NormalChar == parserScanResult && i < len) + { + // skip normal char + continue; + } + + var size = i - copyFrom; + if (ParserScanResult.EscapedChar == parserScanResult) + { + size--; + } + + if (size != 0) + { + var utf8size = Encoding.UTF8.GetBytes(format, copyFrom, size, utf8buffer, bufOffset); + list.Add(new Utf8FormatSegment(bufOffset, utf8size, Utf8FormatSegment.NotFormatIndex, default, 0)); + bufOffset += utf8size; + } + + copyFrom = i; + + if (ParserScanResult.BraceOpen == parserScanResult) + { + break; + } + } + + if (i >= len) + { + break; + } + + // Here it is before `{`. + var indexParse = FormatParser.Parse(format, i); + copyFrom = indexParse.LastIndex; // continue after '}' + i = indexParse.LastIndex; + list.Add(new Utf8FormatSegment(0, 0, indexParse.Index, StandardFormat.Parse(indexParse.FormatString), indexParse.Alignment)); } return list.ToArray(); } } - internal readonly struct FormatSegment + internal readonly struct Utf8FormatSegment { public const int NotFormatIndex = -1; - //public readonly bool IsFormatArgument; + public readonly int Offset; + public readonly int Count; + public readonly int FormatIndex; + public readonly StandardFormat StandardFormat; + public readonly int Alignment; + public bool IsFormatArgument => FormatIndex != NotFormatIndex; + public Utf8FormatSegment(int offset, int count, int formatIndex, StandardFormat format, int alignment) + { + Offset = offset; + Count = count; + FormatIndex = formatIndex; + StandardFormat = format; + Alignment = alignment; + } + } + + internal readonly struct Utf16FormatSegment + { + public const int NotFormatIndex = -1; + public readonly int Offset; public readonly int Count; - public readonly int Alignment; public readonly int FormatIndex; - public readonly string FormatString; + public readonly int Alignment; - // Utf8 - public readonly StandardFormat StandardFormat; + public bool IsFormatArgument => FormatIndex != NotFormatIndex; - public FormatSegment(int offset, int count, int formatIndex, string formatString, bool utf8, int alignment) + public Utf16FormatSegment(int offset, int count, int formatIndex, int alignment) { Offset = offset; Count = count; - //IsFormatArgument = formatIndex != NotFormatIndex; FormatIndex = formatIndex; - FormatString = formatString; Alignment = alignment; - if (utf8) - { - StandardFormat = (formatString != null) ? StandardFormat.Parse(formatString.AsSpan(Offset, Count)) : default; - } - else - { - StandardFormat = default; - } } } } From 1f794e44377b4120c538d6e6bd25e8b8f894bcd7 Mon Sep 17 00:00:00 2001 From: udaken Date: Fri, 7 Aug 2020 20:55:14 +0900 Subject: [PATCH 094/139] minor optimize --- .../Assets/Scripts/ZString/Utf16ValueStringBuilder.cs | 3 +++ .../Assets/Scripts/ZString/Utf8ValueStringBuilder.cs | 3 +++ src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs | 5 +++++ src/ZString/Utf16ValueStringBuilder.cs | 3 +++ src/ZString/Utf8ValueStringBuilder.cs | 3 +++ src/ZString/ZString.Concat.cs | 5 +++++ src/ZString/ZString.Concat.tt | 7 +++++++ 7 files changed, 29 insertions(+) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 7a4368a6..f5feff71 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -512,6 +512,9 @@ public bool TryCopyTo(Span destination, out int charsWritten) /// Converts the value of this instance to a System.String. public override string ToString() { + if (index == 0) + return string.Empty; + return new string(buffer, 0, index); } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 5acbf83a..99ad3c44 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -313,6 +313,9 @@ public Task WriteToAsync(Stream stream) /// Encode the innner utf8 buffer to a System.String. public override string ToString() { + if (index == 0) + return string.Empty; + return UTF8NoBom.GetString(buffer, 0, index); } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs index 2ab15f67..b97088b8 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZString.Concat.cs @@ -7,6 +7,11 @@ public static partial class ZString /// Concatenates the string representation of some specified objects. public static string Concat(T1 arg1) { + if (typeof(T1) == typeof(string)) + { + return (arg1 != null) ? Unsafe.As(arg1) : string.Empty; + } + var sb = new Utf16ValueStringBuilder(true); try { diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 7a4368a6..f5feff71 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -512,6 +512,9 @@ public bool TryCopyTo(Span destination, out int charsWritten) /// Converts the value of this instance to a System.String. public override string ToString() { + if (index == 0) + return string.Empty; + return new string(buffer, 0, index); } diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 5acbf83a..99ad3c44 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -313,6 +313,9 @@ public Task WriteToAsync(Stream stream) /// Encode the innner utf8 buffer to a System.String. public override string ToString() { + if (index == 0) + return string.Empty; + return UTF8NoBom.GetString(buffer, 0, index); } diff --git a/src/ZString/ZString.Concat.cs b/src/ZString/ZString.Concat.cs index 2ab15f67..b97088b8 100644 --- a/src/ZString/ZString.Concat.cs +++ b/src/ZString/ZString.Concat.cs @@ -7,6 +7,11 @@ public static partial class ZString /// Concatenates the string representation of some specified objects. public static string Concat(T1 arg1) { + if (typeof(T1) == typeof(string)) + { + return (arg1 != null) ? Unsafe.As(arg1) : string.Empty; + } + var sb = new Utf16ValueStringBuilder(true); try { diff --git a/src/ZString/ZString.Concat.tt b/src/ZString/ZString.Concat.tt index 4c5f0557..7c9f854e 100644 --- a/src/ZString/ZString.Concat.tt +++ b/src/ZString/ZString.Concat.tt @@ -15,6 +15,13 @@ namespace Cysharp.Text /// Concatenates the string representation of some specified objects. public static string Concat<<#= CreateTypeArgument(i) #>>(<#= CreateParameters(i) #>) { +<# if(i == 1) { #> + if (typeof(T1) == typeof(string)) + { + return (arg1 != null) ? Unsafe.As(arg1) : string.Empty; + } + +<# } #> var sb = new Utf16ValueStringBuilder(true); try { From c250bb63eb2297600f7d0ff71aa65ba621e6ebe1 Mon Sep 17 00:00:00 2001 From: udaken Date: Fri, 7 Aug 2020 22:20:25 +0900 Subject: [PATCH 095/139] optimize for bool type --- ...Utf16ValueStringBuilder.CreateFormatter.cs | 4 ++ .../Utf8ValueStringBuilder.CreateFormatter.cs | 8 +++ ...alueStringBuilder.SpanFormattableAppend.cs | 61 +++++++++++++++++++ src/ZString/T4Common.t4 | 2 + ...Utf16ValueStringBuilder.CreateFormatter.cs | 4 ++ ...Utf16ValueStringBuilder.CreateFormatter.tt | 2 +- .../Utf8ValueStringBuilder.CreateFormatter.cs | 8 +++ .../Utf8ValueStringBuilder.CreateFormatter.tt | 4 +- ...alueStringBuilder.SpanFormattableAppend.cs | 61 +++++++++++++++++++ ...alueStringBuilder.SpanFormattableAppend.tt | 3 +- tests/ZString.Tests/Primitives.cs | 24 ++++++++ 11 files changed, 177 insertions(+), 4 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 8d939c70..9039f7b6 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -126,6 +126,10 @@ static object CreateFormatter(Type type) { return CreateNullableFormatter(); } + if (type == typeof(System.Boolean?)) + { + return CreateNullableFormatter(); + } if (type == typeof(System.IntPtr)) { // ignore format diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index b04471cc..dd58fce1 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -68,6 +68,10 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } + if (type == typeof(System.Boolean)) + { + return new TryFormat((System.Boolean x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } if (type == typeof(System.Byte?)) { return CreateNullableFormatter(); @@ -128,6 +132,10 @@ static object CreateFormatter(Type type) { return CreateNullableFormatter(); } + if (type == typeof(System.Boolean?)) + { + return CreateNullableFormatter(); + } if (type == typeof(System.IntPtr)) { // ignore format diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index 1a46010b..5321ecbf 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -52,6 +52,7 @@ public void AppendLine(System.Byte value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value) @@ -97,6 +98,7 @@ public void AppendLine(System.DateTime value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value) @@ -142,6 +144,7 @@ public void AppendLine(System.DateTimeOffset value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value) @@ -187,6 +190,7 @@ public void AppendLine(System.Decimal value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value) @@ -232,6 +236,7 @@ public void AppendLine(System.Double value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value) @@ -277,6 +282,7 @@ public void AppendLine(System.Int16 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value) @@ -322,6 +328,7 @@ public void AppendLine(System.Int32 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value) @@ -367,6 +374,7 @@ public void AppendLine(System.Int64 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value) @@ -412,6 +420,7 @@ public void AppendLine(System.SByte value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value) @@ -457,6 +466,7 @@ public void AppendLine(System.Single value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value) @@ -502,6 +512,7 @@ public void AppendLine(System.TimeSpan value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value) @@ -547,6 +558,7 @@ public void AppendLine(System.UInt16 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value) @@ -592,6 +604,7 @@ public void AppendLine(System.UInt32 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value) @@ -637,6 +650,7 @@ public void AppendLine(System.UInt64 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value) @@ -682,5 +696,52 @@ public void AppendLine(System.Guid value, StandardFormat format) Append(value, format); AppendLine(); } + + /// Appends the string representation of a specified value to this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Boolean value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(written); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + /// Appends the string representation of a specified value to this instance with numeric format strings. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Boolean value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(written); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Boolean value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Boolean value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + } } diff --git a/src/ZString/T4Common.t4 b/src/ZString/T4Common.t4 index 8ef1a1f4..9bd64b6c 100644 --- a/src/ZString/T4Common.t4 +++ b/src/ZString/T4Common.t4 @@ -41,4 +41,6 @@ typeof(Guid), // typeof(Version), }; + + var utf8spanFormattables = spanFormattables.Append(typeof(bool)); #> \ No newline at end of file diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs index 8d939c70..9039f7b6 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.cs @@ -126,6 +126,10 @@ static object CreateFormatter(Type type) { return CreateNullableFormatter(); } + if (type == typeof(System.Boolean?)) + { + return CreateNullableFormatter(); + } if (type == typeof(System.IntPtr)) { // ignore format diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt index 0ccd7055..6c373fdf 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.CreateFormatter.tt @@ -57,7 +57,7 @@ namespace Cysharp.Text return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, ReadOnlySpan format) => x.TryFormat(dest, out written, format)); } <# } #> -<# foreach(var t in spanFormattables) { #> +<# foreach(var t in spanFormattables.Append(typeof(bool))) { #> if (type == typeof(<#= t.FullName #>?)) { return CreateNullableFormatter<<#= t.FullName #>>(); diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs index b04471cc..dd58fce1 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.cs @@ -68,6 +68,10 @@ static object CreateFormatter(Type type) { return new TryFormat((System.Guid x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } + if (type == typeof(System.Boolean)) + { + return new TryFormat((System.Boolean x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); + } if (type == typeof(System.Byte?)) { return CreateNullableFormatter(); @@ -128,6 +132,10 @@ static object CreateFormatter(Type type) { return CreateNullableFormatter(); } + if (type == typeof(System.Boolean?)) + { + return CreateNullableFormatter(); + } if (type == typeof(System.IntPtr)) { // ignore format diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt index 544198da..bddf1176 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.CreateFormatter.tt @@ -15,13 +15,13 @@ namespace Cysharp.Text { static object CreateFormatter(Type type) { -<# foreach(var t in spanFormattables) { #> +<# foreach(var t in utf8spanFormattables) { #> if (type == typeof(<#= t.FullName #>)) { return new TryFormat<<#= t.FullName #>>((<#= t.FullName #> x, Span dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)); } <# } #> -<# foreach(var t in spanFormattables) { #> +<# foreach(var t in utf8spanFormattables) { #> if (type == typeof(<#= t.FullName #>?)) { return CreateNullableFormatter<<#= t.FullName #>>(); diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs index 1a46010b..5321ecbf 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.cs @@ -52,6 +52,7 @@ public void AppendLine(System.Byte value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTime value) @@ -97,6 +98,7 @@ public void AppendLine(System.DateTime value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.DateTimeOffset value) @@ -142,6 +144,7 @@ public void AppendLine(System.DateTimeOffset value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Decimal value) @@ -187,6 +190,7 @@ public void AppendLine(System.Decimal value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Double value) @@ -232,6 +236,7 @@ public void AppendLine(System.Double value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int16 value) @@ -277,6 +282,7 @@ public void AppendLine(System.Int16 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int32 value) @@ -322,6 +328,7 @@ public void AppendLine(System.Int32 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Int64 value) @@ -367,6 +374,7 @@ public void AppendLine(System.Int64 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.SByte value) @@ -412,6 +420,7 @@ public void AppendLine(System.SByte value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Single value) @@ -457,6 +466,7 @@ public void AppendLine(System.Single value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.TimeSpan value) @@ -502,6 +512,7 @@ public void AppendLine(System.TimeSpan value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt16 value) @@ -547,6 +558,7 @@ public void AppendLine(System.UInt16 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt32 value) @@ -592,6 +604,7 @@ public void AppendLine(System.UInt32 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.UInt64 value) @@ -637,6 +650,7 @@ public void AppendLine(System.UInt64 value, StandardFormat format) Append(value, format); AppendLine(); } + /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(System.Guid value) @@ -682,5 +696,52 @@ public void AppendLine(System.Guid value, StandardFormat format) Append(value, format); AppendLine(); } + + /// Appends the string representation of a specified value to this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Boolean value) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written)) + { + Grow(written); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + /// Appends the string representation of a specified value to this instance with numeric format strings. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(System.Boolean value, StandardFormat format) + { + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out var written, format)) + { + Grow(written); + if(!Utf8Formatter.TryFormat(value, buffer.AsSpan(index), out written, format)) + { + ThrowArgumentException(nameof(value)); + } + } + index += written; + } + + /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Boolean value) + { + Append(value); + AppendLine(); + } + + /// Appends the string representation of a specified value with numeric format strings followed by the default line terminator to the end of this instance. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLine(System.Boolean value, StandardFormat format) + { + Append(value, format); + AppendLine(); + } + } } diff --git a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt index 819f2114..85962641 100644 --- a/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt +++ b/src/ZString/Utf8/Utf8ValueStringBuilder.SpanFormattableAppend.tt @@ -14,7 +14,7 @@ namespace Cysharp.Text { public partial struct Utf8ValueStringBuilder { -<# foreach(var t in spanFormattables) { #> +<# foreach(var t in utf8spanFormattables) { #> /// Appends the string representation of a specified value to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(<#= t.FullName #> value) @@ -60,6 +60,7 @@ namespace Cysharp.Text Append(value, format); AppendLine(); } + <# } #> } } diff --git a/tests/ZString.Tests/Primitives.cs b/tests/ZString.Tests/Primitives.cs index 1a2ed264..d5145d7f 100644 --- a/tests/ZString.Tests/Primitives.cs +++ b/tests/ZString.Tests/Primitives.cs @@ -205,5 +205,29 @@ public void EnumTest() sb1.ToString().Should().Be(sb5.ToString()); } } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void BoolTest(bool x) + { + using (var sb1 = ZString.CreateStringBuilder()) + using (var sb2 = ZString.CreateUtf8StringBuilder()) + using (var sb3 = ZString.CreateStringBuilder()) + using (var sb4 = ZString.CreateUtf8StringBuilder()) + { + var sb5 = new StringBuilder(); + sb1.Append(x); + sb2.Append(x); + sb3.Append(x); + sb4.Append(x); + sb5.Append(x); + + sb1.ToString().Should().Be(sb2.ToString()); + sb1.ToString().Should().Be(sb3.ToString()); + sb1.ToString().Should().Be(sb4.ToString()); + sb1.ToString().Should().Be(sb5.ToString()); + } + } } } From e08b5397194df751a6502eaffcb6127e6b262925 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Tue, 11 Aug 2020 10:29:31 +0900 Subject: [PATCH 096/139] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 51bf51c8..b795bccc 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,6 @@ var str = unboxed.ToString(); License --- -This library is licensed under the the MIT License. +This library is licensed under the MIT License. -.NET Standard 2.0 and Unity version borrows [dotnet/runtime](https://github.com/dotnet/runtime) conversion methods, there exists under `ZString/Number` directory. This third-party license follows [runtime/LICENSE.TXT](https://github.com/dotnet/runtime/blob/master/LICENSE.TXT). \ No newline at end of file +.NET Standard 2.0 and Unity version borrows [dotnet/runtime](https://github.com/dotnet/runtime) conversion methods, there exists under `ZString/Number` directory. This third-party license follows [runtime/LICENSE.TXT](https://github.com/dotnet/runtime/blob/master/LICENSE.TXT). From d33379b03eeae2c658c15af947653e37c331ae68 Mon Sep 17 00:00:00 2001 From: Kamil Szurant Date: Fri, 9 Oct 2020 07:53:50 +0200 Subject: [PATCH 097/139] TMP extension for single file Helpful for numbers --- .../Scripts/ZString/Unity/TextMeshProExtensions.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs index 93c8f6e6..fffb4e48 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Unity/TextMeshProExtensions.cs @@ -5,6 +5,16 @@ namespace Cysharp.Text { public static partial class TextMeshProExtensions { + public static void SetText(this TMP_Text text, T arg0) + { + using ( var sb = new Cysharp.Text.Utf16ValueStringBuilder( true ) ) + { + sb.Append(arg0); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) { using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) @@ -182,4 +192,4 @@ public static void SetTextFormat Date: Wed, 14 Oct 2020 12:21:40 +0900 Subject: [PATCH 098/139] chore: replace set-env to ENV FILE $GITHUB_ENV * fix https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/ * push build on master * use latest dotnet 3.1 --- .github/workflows/build-debug.yml | 4 +- .github/workflows/build-release.yml | 64 ++++++++++++++--------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index 236a6ced..c453a8e2 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -3,7 +3,7 @@ name: Build-Debug on: push: branches: - - "**" + - "master" tags: - "!*" # not a tag push pull_request: @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.101 + dotnet-version: 3.1.x - run: dotnet build src/ZString -c Debug - run: dotnet test tests/ZString.Tests -c Debug < /dev/null diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index a6bbd36a..0d7d58e7 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -16,9 +16,9 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.101 + dotnet-version: 3.1.x # set release tag(*.*.*) to env.GIT_TAG - - run: echo ::set-env name=GIT_TAG::${GITHUB_REF#refs/tags/} + - run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - run: dotnet build src/ZString -c Release -p:Version=${{ env.GIT_TAG }} - run: dotnet test tests/ZString.Tests -c Release --no-build - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} @@ -28,11 +28,11 @@ jobs: with: name: nuget path: ./src/ZString/bin/Release/ZString.${{ env.GIT_TAG }}.nupkg - + build-unity: strategy: matrix: - unity: ['2019.3.9f1'] + unity: ["2019.3.9f1"] include: - unity: 2019.3.9f1 license: UNITY_2019_3 @@ -49,7 +49,7 @@ jobs: - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .Unity.ulf || exit 0 # set release tag(*.*.*) to env.GIT_TAG - - run: echo ::set-env name=GIT_TAG::${GITHUB_REF#refs/tags/} + - run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV # Execute scripts: Export Package - name: Export unitypackage @@ -72,34 +72,34 @@ jobs: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 NUGET_XMLDOC_MODE: skip steps: - # setup dotnet for nuget push - - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 3.1.101 - # set release tag(*.*.*) to env.GIT_TAG - - run: echo ::set-env name=GIT_TAG::${GITHUB_REF#refs/tags/} + # setup dotnet for nuget push + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.x + # set release tag(*.*.*) to env.GIT_TAG + - run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - # Create Releases - - uses: actions/create-release@v1 - id: create_release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Ver.${{ github.ref }} + # Create Releases + - uses: actions/create-release@v1 + id: create_release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Ver.${{ github.ref }} - # Download (All) Artifacts to current directory - - uses: actions/download-artifact@v2-preview + # Download (All) Artifacts to current directory + - uses: actions/download-artifact@v2-preview - # Upload to NuGet - - run: dotnet nuget push "./nuget/*.nupkg" -s https://www.nuget.org/api/v2/package -k ${{ secrets.NUGET_KEY }} + # Upload to NuGet + - run: dotnet nuget push "./nuget/*.nupkg" -s https://www.nuget.org/api/v2/package -k ${{ secrets.NUGET_KEY }} - # Upload to Releases(unitypackage) - - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./ZString.Unity.${{ env.GIT_TAG }}.unitypackage/ZString.Unity.${{ env.GIT_TAG }}.unitypackage - asset_name: ZString.Unity.${{ env.GIT_TAG }}.unitypackage - asset_content_type: application/octet-stream \ No newline at end of file + # Upload to Releases(unitypackage) + - uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./ZString.Unity.${{ env.GIT_TAG }}.unitypackage/ZString.Unity.${{ env.GIT_TAG }}.unitypackage + asset_name: ZString.Unity.${{ env.GIT_TAG }}.unitypackage + asset_content_type: application/octet-stream From f618dee99912c2fbca14c54c7c51966adfac7091 Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 15 Jan 2021 08:02:50 +0900 Subject: [PATCH 099/139] Fix throws exception when enum has same value #32 --- .../Assets/Scripts/ZString/EnumUtil.cs | 19 ++++- src/ZString/EnumUtil.cs | 19 ++++- tests/ZString.Tests/EnumTest.cs | 78 +++++++++++++++++++ 3 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 tests/ZString.Tests/EnumTest.cs diff --git a/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs b/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs index 2548474a..548a58bc 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/EnumUtil.cs @@ -7,6 +7,8 @@ namespace Cysharp.Text { internal static class EnumUtil { + const string InvalidName = "$"; + static readonly Dictionary names; static readonly Dictionary utf8names; @@ -18,14 +20,23 @@ static EnumUtil() utf8names = new Dictionary(enumNames.Length); for (int i = 0; i < enumNames.Length; i++) { - names.Add((T)values.GetValue(i), enumNames[i]); - utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i])); + if (names.ContainsKey((T)values.GetValue(i))) + { + // already registered = invalid. + names[(T)values.GetValue(i)] = InvalidName; + utf8names[(T)values.GetValue(i)] = Array.Empty(); // byte[0] == Invalid. + } + else + { + names.Add((T)values.GetValue(i), enumNames[i]); + utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i])); + } } } public static bool TryFormatUtf16(T value, Span dest, out int written, ReadOnlySpan _) { - if (!names.TryGetValue(value, out var v)) + if (!names.TryGetValue(value, out var v) || v == InvalidName) { v = value.ToString(); } @@ -36,7 +47,7 @@ public static bool TryFormatUtf16(T value, Span dest, out int written, Rea public static bool TryFormatUtf8(T value, Span dest, out int written, StandardFormat _) { - if (!utf8names.TryGetValue(value, out var v)) + if (!utf8names.TryGetValue(value, out var v) || v.Length == 0) { v = Encoding.UTF8.GetBytes(value.ToString()); } diff --git a/src/ZString/EnumUtil.cs b/src/ZString/EnumUtil.cs index 2548474a..548a58bc 100644 --- a/src/ZString/EnumUtil.cs +++ b/src/ZString/EnumUtil.cs @@ -7,6 +7,8 @@ namespace Cysharp.Text { internal static class EnumUtil { + const string InvalidName = "$"; + static readonly Dictionary names; static readonly Dictionary utf8names; @@ -18,14 +20,23 @@ static EnumUtil() utf8names = new Dictionary(enumNames.Length); for (int i = 0; i < enumNames.Length; i++) { - names.Add((T)values.GetValue(i), enumNames[i]); - utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i])); + if (names.ContainsKey((T)values.GetValue(i))) + { + // already registered = invalid. + names[(T)values.GetValue(i)] = InvalidName; + utf8names[(T)values.GetValue(i)] = Array.Empty(); // byte[0] == Invalid. + } + else + { + names.Add((T)values.GetValue(i), enumNames[i]); + utf8names.Add((T)values.GetValue(i), Encoding.UTF8.GetBytes(enumNames[i])); + } } } public static bool TryFormatUtf16(T value, Span dest, out int written, ReadOnlySpan _) { - if (!names.TryGetValue(value, out var v)) + if (!names.TryGetValue(value, out var v) || v == InvalidName) { v = value.ToString(); } @@ -36,7 +47,7 @@ public static bool TryFormatUtf16(T value, Span dest, out int written, Rea public static bool TryFormatUtf8(T value, Span dest, out int written, StandardFormat _) { - if (!utf8names.TryGetValue(value, out var v)) + if (!utf8names.TryGetValue(value, out var v) || v.Length == 0) { v = Encoding.UTF8.GetBytes(value.ToString()); } diff --git a/tests/ZString.Tests/EnumTest.cs b/tests/ZString.Tests/EnumTest.cs new file mode 100644 index 00000000..cd259f93 --- /dev/null +++ b/tests/ZString.Tests/EnumTest.cs @@ -0,0 +1,78 @@ +using Cysharp.Text; +using FluentAssertions; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public enum DuplicateEnum + { + A = 1, + B = 2, + BB = 2, + C = 3 + } + + public enum StandardEnum + { + Abc = 1, + Def = 2, + Ghi = 3, + } + + [Flags] + public enum FlagsEnum + { + None = 0, + Abc = 1, + Bcd = 2, + Efg = 4, + } + + public class EnumTest + { + [Fact] + public void Duplicate() + { + ZString.Format("{0}", DuplicateEnum.A).Should().Be("A"); + ZString.Format("{0}", DuplicateEnum.B).Should().Be("B"); + ZString.Format("{0}", DuplicateEnum.BB).Should().Be("B"); + ZString.Format("{0}", DuplicateEnum.C).Should().Be("C"); + Utf8(DuplicateEnum.A); + Utf8(DuplicateEnum.B); + Utf8(DuplicateEnum.BB); + Utf8(DuplicateEnum.C); + } + + [Fact] + public void Standard() + { + ZString.Format("{0}", StandardEnum.Abc).Should().Be("Abc"); + ZString.Format("{0}", StandardEnum.Def).Should().Be("Def"); + ZString.Format("{0}", StandardEnum.Ghi).Should().Be("Ghi"); + Utf8(StandardEnum.Abc); + Utf8(StandardEnum.Def); + Utf8(StandardEnum.Ghi); + } + + [Fact] + public void Flags() + { + ZString.Format("{0}", FlagsEnum.Abc | FlagsEnum.Bcd).Should().Be("Abc, Bcd"); + ZString.Format("{0}", FlagsEnum.None).Should().Be("None"); + ZString.Format("{0}", FlagsEnum.Efg).Should().Be("Efg"); + Utf8(FlagsEnum.Abc | FlagsEnum.Bcd); + Utf8(FlagsEnum.None); + Utf8(FlagsEnum.Efg); + } + + static void Utf8(T e) where T : Enum + { + var s = ZString.CreateUtf8StringBuilder(); + s.AppendFormat("{0}", e); + s.AsSpan().SequenceEqual(Encoding.UTF8.GetBytes(e.ToString())).Should().BeTrue(); + } + } +} From 7e2fefade477ee1f27c3c3ce03dbaeb5374c5cd7 Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 15 Jan 2021 08:03:12 +0900 Subject: [PATCH 100/139] fix memory leak in Utf16ValueStringBuilder.Insert #36 --- .../Assets/Scripts/ZString/Utf16ValueStringBuilder.cs | 8 ++++++++ src/ZString/Utf16ValueStringBuilder.cs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 518803cc..827192f5 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -309,6 +309,14 @@ public void Insert(int index, ReadOnlySpan value, int count) int remainLnegth = this.index - index; buffer.AsSpan(index, remainLnegth).CopyTo(newBuffer.AsSpan(newBufferIndex)); + if (buffer.Length != ThreadStaticBufferSize) + { + if (buffer != null) + { + ArrayPool.Shared.Return(buffer); + } + } + buffer = newBuffer; this.index = newBufferIndex + remainLnegth; } diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 518803cc..827192f5 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -309,6 +309,14 @@ public void Insert(int index, ReadOnlySpan value, int count) int remainLnegth = this.index - index; buffer.AsSpan(index, remainLnegth).CopyTo(newBuffer.AsSpan(newBufferIndex)); + if (buffer.Length != ThreadStaticBufferSize) + { + if (buffer != null) + { + ArrayPool.Shared.Return(buffer); + } + } + buffer = newBuffer; this.index = newBufferIndex + remainLnegth; } From 31f8f14f2c149f26f4944a6af46f91cadd805f5a Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 15 Jan 2021 08:04:24 +0900 Subject: [PATCH 101/139] ready for 2.3.0 --- src/ZString.Unity/Assets/Scripts/ZString/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json b/src/ZString.Unity/Assets/Scripts/ZString/package.json index d2c495b5..3939e4b6 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/package.json +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json @@ -1,7 +1,7 @@ { "name": "com.cysharp.zstring", "displayName": "ZString", - "version": "2.2.0", + "version": "2.3.0", "unity": "2018.4", "description": "Zero Allocation StringBuilder for .NET Core and Unity.", "keywords": [ "String", "Performance" ], From e979a7e68507c01b1d3af26520a248eb61f3c19d Mon Sep 17 00:00:00 2001 From: neuecc Date: Wed, 20 Jan 2021 16:26:32 +0900 Subject: [PATCH 102/139] add .meta --- .../Scripts/ZString/FormatHelper.cs.meta | 11 ++++++ .../PackageManagerSettings.asset | 38 +++++++++++++++++++ .../ProjectSettings/ProjectVersion.txt | 4 +- 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs.meta create mode 100644 src/ZString.Unity/ProjectSettings/PackageManagerSettings.asset diff --git a/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs.meta new file mode 100644 index 00000000..37046650 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/FormatHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e46453b986ebf4428a5c23fb3cbb175 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/ProjectSettings/PackageManagerSettings.asset b/src/ZString.Unity/ProjectSettings/PackageManagerSettings.asset new file mode 100644 index 00000000..9418901f --- /dev/null +++ b/src/ZString.Unity/ProjectSettings/PackageManagerSettings.asset @@ -0,0 +1,38 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 61 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor:UnityEditor.PackageManager.UI:PackageManagerProjectSettings + m_ScopedRegistriesSettingsExpanded: 1 + oneTimeWarningShown: 0 + m_Registries: + - m_Id: main + m_Name: + m_Url: https://packages.unity.com + m_Scopes: [] + m_IsDefault: 1 + m_UserSelectedRegistryName: + m_UserAddingNewScopedRegistry: 0 + m_RegistryInfoDraft: + m_ErrorMessage: + m_Original: + m_Id: + m_Name: + m_Url: + m_Scopes: [] + m_IsDefault: 0 + m_Modified: 0 + m_Name: + m_Url: + m_Scopes: + - + m_SelectedScopeIndex: 0 diff --git a/src/ZString.Unity/ProjectSettings/ProjectVersion.txt b/src/ZString.Unity/ProjectSettings/ProjectVersion.txt index 291a7485..a1914810 100644 --- a/src/ZString.Unity/ProjectSettings/ProjectVersion.txt +++ b/src/ZString.Unity/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2019.4.5f1 -m_EditorVersionWithRevision: 2019.4.5f1 (81610f64359c) +m_EditorVersion: 2019.4.14f1 +m_EditorVersionWithRevision: 2019.4.14f1 (4037e52648cd) From a56ac542753eae6d956c4fc8aaf715cd9f680b79 Mon Sep 17 00:00:00 2001 From: neuecc Date: Wed, 20 Jan 2021 16:27:00 +0900 Subject: [PATCH 103/139] package.json for 2.3.1 --- src/ZString.Unity/Assets/Scripts/ZString/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json b/src/ZString.Unity/Assets/Scripts/ZString/package.json index 3939e4b6..4200f572 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/package.json +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json @@ -1,7 +1,7 @@ { "name": "com.cysharp.zstring", "displayName": "ZString", - "version": "2.3.0", + "version": "2.3.1", "unity": "2018.4", "description": "Zero Allocation StringBuilder for .NET Core and Unity.", "keywords": [ "String", "Performance" ], From 434193d0386f32ec219139c6a487434f63e11f92 Mon Sep 17 00:00:00 2001 From: Gilberto Bittencourt Date: Sun, 24 Jan 2021 06:59:28 -0300 Subject: [PATCH 104/139] added managed dlls as samples --- .../Plugins/System.Buffers.dll | Bin 0 -> 28304 bytes .../Plugins/System.Buffers.dll.meta | 33 ++++++++++++++++++ .../Plugins/System.Memory.dll | Bin 0 -> 148760 bytes .../Plugins/System.Memory.dll.meta | 33 ++++++++++++++++++ ...System.Runtime.CompilerServices.Unsafe.dll | Bin 0 -> 16968 bytes ...m.Runtime.CompilerServices.Unsafe.dll.meta | 33 ++++++++++++++++++ .../Assets/Scripts/ZString/package.json | 9 ++++- 7 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Buffers.dll create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Buffers.dll.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Memory.dll create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Memory.dll.meta create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Runtime.CompilerServices.Unsafe.dll create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Runtime.CompilerServices.Unsafe.dll.meta diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Buffers.dll b/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Buffers.dll new file mode 100644 index 0000000000000000000000000000000000000000..c517a3b62cc7e190fb347c00a960311a9349b53c GIT binary patch literal 28304 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 the string representation of a specified value followed by the default line terminator to the end of this instance. @@ -219,7 +228,7 @@ public void Append(ReadOnlySpan value) { Grow(value.Length); } - + value.CopyTo(buffer.AsSpan(index)); index += value.Length; } @@ -369,7 +378,7 @@ public void Replace(char oldChar, char newChar, int startIndex, int count) /// are removed from this builder. /// public void Replace(string oldValue, string newValue) => Replace(oldValue, newValue, 0, Length); - + public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue) => Replace(oldValue, newValue, 0, Length); /// diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index e141402a..b1d4419e 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -200,7 +200,16 @@ public void AppendLine(char value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { +#if UNITY_2018_3_OR_NEWER + if (buffer.Length - index < value.Length) + { + Grow(value.Length); + } + value.CopyTo(0, buffer, index, value.Length); + index += value.Length; +#else Append(value.AsSpan()); +#endif } /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. @@ -219,7 +228,7 @@ public void Append(ReadOnlySpan value) { Grow(value.Length); } - + value.CopyTo(buffer.AsSpan(index)); index += value.Length; } @@ -369,7 +378,7 @@ public void Replace(char oldChar, char newChar, int startIndex, int count) /// are removed from this builder. /// public void Replace(string oldValue, string newValue) => Replace(oldValue, newValue, 0, Length); - + public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue) => Replace(oldValue, newValue, 0, Length); /// From 2b477cb7b556e06bb30f8f375573658caf44b407 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 13 Apr 2021 13:59:48 +0900 Subject: [PATCH 120/139] improve Utf8ValueStringBuilder.Append performance --- .../Benchmarks/AppendPerformance.cs | 49 +++++++++++++++++++ sandbox/PerfBenchmark/Program.cs | 2 +- .../Scripts/ZString/Utf8ValueStringBuilder.cs | 13 ++++- src/ZString/Utf8ValueStringBuilder.cs | 13 ++++- 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/sandbox/PerfBenchmark/Benchmarks/AppendPerformance.cs b/sandbox/PerfBenchmark/Benchmarks/AppendPerformance.cs index b9163159..58338489 100644 --- a/sandbox/PerfBenchmark/Benchmarks/AppendPerformance.cs +++ b/sandbox/PerfBenchmark/Benchmarks/AppendPerformance.cs @@ -70,4 +70,53 @@ public void StringBuilder() } } } + + + [Config(typeof(BenchmarkConfig))] + public class Utf8AppendPerformance + { + List strings; + const int COUNT = 1000; + + public Utf8AppendPerformance() + { + strings = new List(); + for (int i = 0; i < 100; i++) + { + strings.Add("123456789"); + } + } + + [Benchmark] + public void ZStringUtf8() + { + for (int i = 0; i < COUNT; i++) + { + using (var sb = ZString.CreateUtf8StringBuilder()) + { + for (int j = 0; j < strings.Count; j++) + { + sb.Append(strings[j]); + } + + _ = sb.AsSpan().ToArray(); + } + } + } + + [Benchmark(Baseline = true)] + public void StringBuilder() + { + for (int i = 0; i < COUNT; i++) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + for (int j = 0; j < strings.Count; j++) + { + sb.Append(strings[j]); + } + + _ = sb.ToString(); + } + } + } } diff --git a/sandbox/PerfBenchmark/Program.cs b/sandbox/PerfBenchmark/Program.cs index 690575e2..4d04d965 100644 --- a/sandbox/PerfBenchmark/Program.cs +++ b/sandbox/PerfBenchmark/Program.cs @@ -21,7 +21,7 @@ public BenchmarkConfig() AddJob(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1).WithRuntime(CoreRuntime.Core50)); // Add Targetframeworks net47 to csproj(removed for CI) - // AddJob(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1).WithRuntime(ClrRuntime.Net47)); + //AddJob(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1).WithRuntime(ClrRuntime.Net47)); } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index d47df720..0c66add1 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -41,7 +41,7 @@ static Utf8ValueStringBuilder() static byte[] scratchBuffer; [ThreadStatic] - internal static bool scratchBufferUsed; + internal static bool scratchBufferUsed; byte[] buffer; int index; @@ -199,7 +199,7 @@ public void Append(char value, int repeatCount) Advance(repeatCount); } else - { + { var maxLen = UTF8NoBom.GetMaxByteCount(1); Span utf8Bytes = stackalloc byte[maxLen]; ReadOnlySpan chars = stackalloc char[1] { value }; @@ -228,7 +228,16 @@ public void AppendLine(char value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { +#if UNITY_2018_3_OR_NEWER + var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); + if (buffer.Length - index < maxLen) + { + Grow(maxLen); + } + index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); +#else Append(value.AsSpan()); +#endif } /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index d47df720..0c66add1 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -41,7 +41,7 @@ static Utf8ValueStringBuilder() static byte[] scratchBuffer; [ThreadStatic] - internal static bool scratchBufferUsed; + internal static bool scratchBufferUsed; byte[] buffer; int index; @@ -199,7 +199,7 @@ public void Append(char value, int repeatCount) Advance(repeatCount); } else - { + { var maxLen = UTF8NoBom.GetMaxByteCount(1); Span utf8Bytes = stackalloc byte[maxLen]; ReadOnlySpan chars = stackalloc char[1] { value }; @@ -228,7 +228,16 @@ public void AppendLine(char value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { +#if UNITY_2018_3_OR_NEWER + var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); + if (buffer.Length - index < maxLen) + { + Grow(maxLen); + } + index += UTF8NoBom.GetBytes(value, 0, value.Length, buffer, index); +#else Append(value.AsSpan()); +#endif } /// Appends the string representation of a specified value followed by the default line terminator to the end of this instance. From 48a6d75f939c0c9d0d0c2a80aaa620b3603f57af Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 13 Apr 2021 05:00:33 +0000 Subject: [PATCH 121/139] feat: Update package.json to 2.4.1 --- src/ZString.Unity/Assets/Scripts/ZString/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json b/src/ZString.Unity/Assets/Scripts/ZString/package.json index ac5fa73a..6f9f81ec 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/package.json +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json @@ -1,7 +1,7 @@ { "name": "com.cysharp.zstring", "displayName": "ZString", - "version": "2.4.0", + "version": "2.4.1", "unity": "2018.4", "description": "Zero Allocation StringBuilder for .NET Core and Unity.", "keywords": [ From 55dd1e31121e1a18913da023397138445189cc8f Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Mon, 19 Apr 2021 18:49:47 +0900 Subject: [PATCH 122/139] shore: skip ci supported by default --- .github/workflows/build-debug.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index 971eb82d..d2c6214d 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -12,7 +12,6 @@ on: jobs: build-dotnet: - if: "!(contains(github.event.head_commit.message, '[skip ci]') || contains(github.event.head_commit.message, '[ci skip]'))" runs-on: ubuntu-latest env: DOTNET_CLI_TELEMETRY_OPTOUT: 1 @@ -27,7 +26,7 @@ jobs: - run: dotnet test tests/ZString.Tests -c Debug < /dev/null build-unity: - if: "!(contains(github.event.head_commit.message, '[skip ci]') || contains(github.event.head_commit.message, '[ci skip]')) && ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:'))" + if: "((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:'))" strategy: matrix: unity: ["2019.3.9f1", "2019.4.13f1", "2020.1.12f1"] From ed9afed9dafd3674639996dec1b80e89caf33f70 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Fri, 23 Apr 2021 09:23:53 +0300 Subject: [PATCH 123/139] Add ZStringWriter --- src/ZString/ZStringWriter.cs | 207 +++++++++++++++++++++++ tests/ZString.Tests/ZStringWriterTest.cs | 37 ++++ 2 files changed, 244 insertions(+) create mode 100644 src/ZString/ZStringWriter.cs create mode 100644 tests/ZString.Tests/ZStringWriterTest.cs diff --git a/src/ZString/ZStringWriter.cs b/src/ZString/ZStringWriter.cs new file mode 100644 index 00000000..862e56c0 --- /dev/null +++ b/src/ZString/ZStringWriter.cs @@ -0,0 +1,207 @@ +using System; +using System.Globalization; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Cysharp.Text +{ + /// + /// A implementation that is backed with . + /// + /// + /// It's important to make sure the writer is always properly disposed. + /// + public sealed class ZStringWriter : TextWriter + { + private Utf16ValueStringBuilder sb; + private bool isOpen; + private UnicodeEncoding encoding; + + /// + /// Creates a new instance using as format provider. + /// + public ZStringWriter() : this(CultureInfo.CurrentCulture) + { + } + + /// + /// Creates a new instance with given format provider. + /// + public ZStringWriter(IFormatProvider formatProvider) : base(formatProvider) + { + sb = ZString.CreateStringBuilder(); + isOpen = true; + } + + /// + /// Disposes this instance, operations are no longer allowed. + /// + public override void Close() + { + Dispose(true); + } + + protected override void Dispose(bool disposing) + { + sb.Dispose(); + isOpen = false; + base.Dispose(disposing); + } + + public override Encoding Encoding => encoding = encoding ?? new UnicodeEncoding(false, false); + + public override void Write(char value) + { + AssertNotDisposed(); + + sb.Append(value); + } + + public override void Write(char[] buffer, int index, int count) + { + if (buffer == null) + { + throw new ArgumentNullException(nameof(buffer)); + } + if (index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + if (buffer.Length - index < count) + { + throw new ArgumentException(); + } + AssertNotDisposed(); + + sb.Append(buffer.AsSpan(index, count)); + } + + public override void Write(string value) + { + AssertNotDisposed(); + + if (value != null) + { + sb.Append(value); + } + } + + public override Task WriteAsync(char value) + { + Write(value); + return Task.CompletedTask; + } + + public override Task WriteAsync(string value) + { + Write(value); + return Task.CompletedTask; + } + + public override Task WriteAsync(char[] buffer, int index, int count) + { + Write(buffer, index, count); + return Task.CompletedTask; + } + + public override Task WriteLineAsync(char value) + { + WriteLine(value); + return Task.CompletedTask; + } + + public override Task WriteLineAsync(string value) + { + WriteLine(value); + return Task.CompletedTask; + } + + public override Task WriteLineAsync(char[] buffer, int index, int count) + { + WriteLine(buffer, index, count); + return Task.CompletedTask; + } + + public override void Write(bool value) + { + AssertNotDisposed(); + sb.Append(value); + } + + public override void Write(decimal value) + { + AssertNotDisposed(); + sb.Append(value); + } + + /// + /// No-op. + /// + public override Task FlushAsync() + { + return Task.CompletedTask; + } + + /// + /// Materializes the current state from underlying string builder. + /// + public override string ToString() + { + return sb.ToString(); + } + +#if !NETSTANDARD2_0 + + public override void Write(ReadOnlySpan buffer) + { + AssertNotDisposed(); + + sb.Append(buffer); + } + + public override void WriteLine(ReadOnlySpan buffer) + { + AssertNotDisposed(); + + sb.Append(buffer); + WriteLine(); + } + + public override Task WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + Write(buffer.Span); + return Task.CompletedTask; + } + + public override Task WriteLineAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + WriteLine(buffer.Span); + return Task.CompletedTask; + } +#endif + + private void AssertNotDisposed() + { + if (!isOpen) + { + throw new ObjectDisposedException(nameof(sb)); + } + } + } +} diff --git a/tests/ZString.Tests/ZStringWriterTest.cs b/tests/ZString.Tests/ZStringWriterTest.cs new file mode 100644 index 00000000..30539346 --- /dev/null +++ b/tests/ZString.Tests/ZStringWriterTest.cs @@ -0,0 +1,37 @@ +using System; +using Cysharp.Text; +using Xunit; + +namespace ZStringTests +{ + public class ZStringWriterTest + { + [Fact] + public void DoubleDisposeTest() + { + var sb = new ZStringWriter(); + sb.Dispose(); + sb.Dispose(); // call more than once + } + + [Fact] + public void BasicWrites() + { + using (var writer = new ZStringWriter()) + { + writer.Write("text1".AsSpan()); + writer.Write("text2"); + writer.Write('c'); + writer.Write(true); + writer.Write(123); + writer.Write(456f); + writer.Write(789d); + writer.Write("end".AsMemory()); + writer.WriteLine(); + + var expected = "text1text2cTrue123456789end" + Environment.NewLine; + Assert.Equal(expected, writer.ToString()); + } + } + } +} \ No newline at end of file From 67806444dfa95d1098244e5e61e1db2053c94d3a Mon Sep 17 00:00:00 2001 From: neuecc Date: Fri, 30 Apr 2021 14:26:40 +0900 Subject: [PATCH 124/139] ZStringWriter for Unity --- .../Assets/Scripts/ZString/ZStringWriter.cs | 209 ++++++++++++++++++ .../Scripts/ZString/ZStringWriter.cs.meta | 11 + src/ZString/Icon.png | Bin 0 -> 3185 bytes src/ZString/ZString.csproj | 5 + src/ZString/ZStringWriter.cs | 4 +- 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs create mode 100644 src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs.meta create mode 100644 src/ZString/Icon.png diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs new file mode 100644 index 00000000..70580645 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs @@ -0,0 +1,209 @@ +using System; +using System.Globalization; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Cysharp.Text +{ + /// + /// A implementation that is backed with . + /// + /// + /// It's important to make sure the writer is always properly disposed. + /// + public sealed class ZStringWriter : TextWriter + { + private Utf16ValueStringBuilder sb; + private bool isOpen; + private UnicodeEncoding encoding; + + /// + /// Creates a new instance using as format provider. + /// + public ZStringWriter() : this(CultureInfo.CurrentCulture) + { + } + + /// + /// Creates a new instance with given format provider. + /// + public ZStringWriter(IFormatProvider formatProvider) : base(formatProvider) + { + sb = ZString.CreateStringBuilder(); + isOpen = true; + } + + /// + /// Disposes this instance, operations are no longer allowed. + /// + public override void Close() + { + Dispose(true); + } + + protected override void Dispose(bool disposing) + { + sb.Dispose(); + isOpen = false; + base.Dispose(disposing); + } + + public override Encoding Encoding => encoding = encoding ?? new UnicodeEncoding(false, false); + + public override void Write(char value) + { + AssertNotDisposed(); + + sb.Append(value); + } + + public override void Write(char[] buffer, int index, int count) + { + if (buffer == null) + { + throw new ArgumentNullException(nameof(buffer)); + } + if (index < 0) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + if (count < 0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + if (buffer.Length - index < count) + { + throw new ArgumentException(); + } + AssertNotDisposed(); + + sb.Append(buffer.AsSpan(index, count)); + } + + public override void Write(string value) + { + AssertNotDisposed(); + + if (value != null) + { + sb.Append(value); + } + } + + public override Task WriteAsync(char value) + { + Write(value); + return Task.CompletedTask; + } + + public override Task WriteAsync(string value) + { + Write(value); + return Task.CompletedTask; + } + + public override Task WriteAsync(char[] buffer, int index, int count) + { + Write(buffer, index, count); + return Task.CompletedTask; + } + + public override Task WriteLineAsync(char value) + { + WriteLine(value); + return Task.CompletedTask; + } + + public override Task WriteLineAsync(string value) + { + WriteLine(value); + return Task.CompletedTask; + } + + public override Task WriteLineAsync(char[] buffer, int index, int count) + { + WriteLine(buffer, index, count); + return Task.CompletedTask; + } + + public override void Write(bool value) + { + AssertNotDisposed(); + sb.Append(value); + } + + public override void Write(decimal value) + { + AssertNotDisposed(); + sb.Append(value); + } + + /// + /// No-op. + /// + public override Task FlushAsync() + { + return Task.CompletedTask; + } + + /// + /// Materializes the current state from underlying string builder. + /// + public override string ToString() + { + return sb.ToString(); + } + +#if !NETSTANDARD2_0 +#if !UNITY_2018_3_OR_NEWER + + public override void Write(ReadOnlySpan buffer) + { + AssertNotDisposed(); + + sb.Append(buffer); + } + + public override void WriteLine(ReadOnlySpan buffer) + { + AssertNotDisposed(); + + sb.Append(buffer); + WriteLine(); + } + + public override Task WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + Write(buffer.Span); + return Task.CompletedTask; + } + + public override Task WriteLineAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + WriteLine(buffer.Span); + return Task.CompletedTask; + } +#endif +#endif + + private void AssertNotDisposed() + { + if (!isOpen) + { + throw new ObjectDisposedException(nameof(sb)); + } + } + } +} diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs.meta b/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs.meta new file mode 100644 index 00000000..947e4fbd --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eb2ec9ac9521172449dbeac815854188 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString/Icon.png b/src/ZString/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..68d64b1e0e5c10200e85a15ab96a0b43ff989f79 GIT binary patch literal 3185 zcmd5;4NOy46uwx2tpaMaI1$0bD9cb;bOT$#Jv;m%3Mq&bl}?@1ZbI#}yg3*kV$i6I z%n`;CD5ao)fT(j?N@H=+un42n1zIT}0voTZSeaE+qNwO&Ktb}oNr~~ah!x^+s2{b zQJT#p9z!#Dn}bPg-tNur*=7=(f94I8n;Z7DGJ!F;JsR0GpKXCJ2wBF-AI@M@4;CEg z40{3fzuNuRjb6C?pO!`}3iB-|$VuTgYD%^by4@hT@-G9N@-2^|z&EGVUn5#=d|~eF zRN85^^M$yBUuQg8Ct_*YK0(aY`5jN@SabYEyWIyGuZYCG?6TVQaz;j|GH@2-w!vS} zWVLK}CeHJ7gDNzG0T)fb9I1uj#P++D%YZkNm7suPuSHRlb%Nzup_eD~?uGj&wJ_fg z)G@k#LQ6X<&Bwc?^tq(Rv^Z+$miNh5p$fWo`UITPg2_4s z^o`Qg#@gr`aHw~aP&|=ns{=pAf*DMCW~?%BeZukvU*QvtP9+laEd94HE8J8yD$kk% z=>x$#S97ZL9Y@r~1B$sL;Vry@w(yV?P`1onHO*A3ulr>4WNBwZ$r~dTQv;DMnNzot z9vQ4=Ez}sF)M%_c@#{y3T%=lVo>&a9_)J8WjG=*py?t8DVRE{pIXDGnxIj0kM^nCi zB?xr9F8R^a=rdxlCX#BcGo5-ReHdTKN6RCQlChO@?4$P zw{qyVyh2MzDc8b8K-)1`qz3k}H?r8mL>^$4paNB-jx?ac_2OJc^$^CO)ErD4lBxfW zk>Q+AfH{B8#Gy7O0B9hDdw;3xGea=3p$5YggQ*7-yA`J|dL3;XRz2qFDbTUe0R%b= zt7lmXMC^cq8tPe!XScg~kgAI=6`pWs{hfM##3Qy<+xOdEWT-Hq55oxQN~vi<7YnIT z^ZFd`kKK_bcGk^^mzd_o)w`xu34{6Mtz3a`7R7}d;J zy*6U0ki*hzbH1i006}IFs^3w@ksd_eFzJUR^c70-E8Ntf({b#p@X|=Jn7TlNSc2=+ zvus?$jOe)ur;ZGkLf~MKyp3uB@uh@ot<9PE4sI0P&s#}*b9a4(JX5gEkgw6D^DG?; nKbDmhcKT)eOmzPo{ZI~Qz{z@ji^5RskI;mzjtH%0Z_oS(cSy02 literal 0 HcmV?d00001 diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index f8118d30..4474fcec 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -20,8 +20,13 @@ MIT true ../../opensource.snk + Icon.png + + + + diff --git a/src/ZString/ZStringWriter.cs b/src/ZString/ZStringWriter.cs index 862e56c0..70580645 100644 --- a/src/ZString/ZStringWriter.cs +++ b/src/ZString/ZStringWriter.cs @@ -157,6 +157,7 @@ public override string ToString() } #if !NETSTANDARD2_0 +#if !UNITY_2018_3_OR_NEWER public override void Write(ReadOnlySpan buffer) { @@ -195,7 +196,8 @@ public override Task WriteLineAsync(ReadOnlyMemory buffer, CancellationTok return Task.CompletedTask; } #endif - +#endif + private void AssertNotDisposed() { if (!isOpen) From 044a79a234ec01a3004fdaf5127febd77d497c70 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 30 Apr 2021 05:32:15 +0000 Subject: [PATCH 125/139] feat: Update package.json to 2.4.2 --- src/ZString.Unity/Assets/Scripts/ZString/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json b/src/ZString.Unity/Assets/Scripts/ZString/package.json index 6f9f81ec..bb2dd340 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/package.json +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json @@ -1,7 +1,7 @@ { "name": "com.cysharp.zstring", "displayName": "ZString", - "version": "2.4.1", + "version": "2.4.2", "unity": "2018.4", "description": "Zero Allocation StringBuilder for .NET Core and Unity.", "keywords": [ From de7740479fd6e6fc768f34ee9526aba007ddc842 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Fri, 30 Apr 2021 14:45:37 +0900 Subject: [PATCH 126/139] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index d9329f6a..3071c5e3 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,11 @@ Reference | `Format` | string | Replaces one or more format items in a string with the string representation of some specified values. | | `FormatTo(ref TBufferWriter, T1,..,T16)` | void | Replaces one or more format items in a string with the string representation of some specified values. | +**class ZStringWriter : TextWriter** + +A `TextWriter` implementation that is backed with `Utf16ValueStringBuilder` +It's important to make sure the writer is always properly disposed. + **static class TextMeshProExtensions**(Unity only) | method | returns | description | From 335d4a3d08c2669a1f23bd21c18a154b5b23cba3 Mon Sep 17 00:00:00 2001 From: Andrew El Date: Thu, 6 May 2021 21:48:52 -0400 Subject: [PATCH 127/139] add ReplaceAt method to Utf16ValueStringBuilder --- .../Scripts/ZString/Utf16ValueStringBuilder.cs | 16 ++++++++++++++++ src/ZString/Utf16ValueStringBuilder.cs | 16 ++++++++++++++++ tests/ZString.Tests/ReplaceTest.cs | 13 +++++++++++++ 3 files changed, 45 insertions(+) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index b1d4419e..63e634fd 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -469,6 +469,22 @@ public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue, in buffer = newBuffer; index = newBufferIndex; } + + /// + /// Replaces the contents of a single position within the builder. + /// + /// The character to use at the position. + /// The index to replace. + public void ReplaceAt(char newChar, int replaceIndex) + { + int currentLength = Length; + if ((uint)replaceIndex > (uint)currentLength) + { + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(replaceIndex)); + } + + buffer[replaceIndex] = newChar; + } /// /// Removes a range of characters from this builder. diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index b1d4419e..63e634fd 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -469,6 +469,22 @@ public void Replace(ReadOnlySpan oldValue, ReadOnlySpan newValue, in buffer = newBuffer; index = newBufferIndex; } + + /// + /// Replaces the contents of a single position within the builder. + /// + /// The character to use at the position. + /// The index to replace. + public void ReplaceAt(char newChar, int replaceIndex) + { + int currentLength = Length; + if ((uint)replaceIndex > (uint)currentLength) + { + ExceptionUtil.ThrowArgumentOutOfRangeException(nameof(replaceIndex)); + } + + buffer[replaceIndex] = newChar; + } /// /// Removes a range of characters from this builder. diff --git a/tests/ZString.Tests/ReplaceTest.cs b/tests/ZString.Tests/ReplaceTest.cs index 25f7f34e..8b25eb14 100644 --- a/tests/ZString.Tests/ReplaceTest.cs +++ b/tests/ZString.Tests/ReplaceTest.cs @@ -7,6 +7,19 @@ namespace ZStringTests { public class ReplaceTest { + + [Fact] + public void ReplaceAtCharTest() + { + var s = new string(' ', 10); + using (var zsb = ZString.CreateStringBuilder()) + { + zsb.Append(s); + zsb.ReplaceAt('-',2); + zsb.ToString().Should().Be(new StringBuilder(s) { [2] = '-'}.ToString()); + } + } + [Fact] public void ReplaceCharTest() { From bb447bc7cc47e4b8f33675163b02238ff215957d Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Mon, 24 May 2021 11:06:24 +0900 Subject: [PATCH 128/139] chore: remove setup-dotnet --- .github/workflows/build-debug.yml | 3 --- .github/workflows/build-release.yml | 7 ------- 2 files changed, 10 deletions(-) diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index d2c6214d..974e62b1 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -19,9 +19,6 @@ jobs: NUGET_XMLDOC_MODE: skip steps: - uses: actions/checkout@v2 - - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 3.1.x - run: dotnet build src/ZString -c Debug - run: dotnet test tests/ZString.Tests -c Debug < /dev/null diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 7d5aa957..8b040871 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -15,7 +15,6 @@ env: GIT_TAG: ${{ github.event.inputs.tag }} DRY_RUN: ${{ github.event.inputs.dry_run }} DRY_RUN_BRANCH_PREFIX: "test_release" - DOTNET_SDK_VERISON_3: 3.1.x jobs: update-packagejson: @@ -85,9 +84,6 @@ jobs: - uses: actions/checkout@v2 with: ref: ${{ needs.update-packagejson.outputs.sha }} - - uses: actions/setup-dotnet@v1 - with: - dotnet-version: "${{ env.DOTNET_SDK_VERSION_3 }}" - run: dotnet build src/ZString -c Release -p:Version=${{ env.GIT_TAG }} - run: dotnet test tests/ZString.Tests -c Release --no-build - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} -o ./publish @@ -150,9 +146,6 @@ jobs: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 NUGET_XMLDOC_MODE: skip steps: - - uses: actions/setup-dotnet@v1 - with: - dotnet-version: "${{ env.DOTNET_SDK_VERSION_3 }}" # Create Release - uses: actions/create-release@v1 id: create_release From 9a6fed52915f7595eb2e9868fd8775dce5633dcc Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 9 Jun 2021 21:22:32 +1000 Subject: [PATCH 129/139] remove some redundant methods --- .../NestedStringBuilderCreationException.cs | 4 ---- .../ZString/Utf16ValueStringBuilder.cs | 19 +------------------ .../NestedStringBuilderCreationException.cs | 4 ---- src/ZString/Utf16ValueStringBuilder.cs | 19 +------------------ 4 files changed, 2 insertions(+), 44 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs b/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs index 4f263d94..ba88121f 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/NestedStringBuilderCreationException.cs @@ -5,10 +5,6 @@ namespace Cysharp.Text // Currently, this class is internals. internal class NestedStringBuilderCreationException : InvalidOperationException { - private NestedStringBuilderCreationException() - { - } - internal protected NestedStringBuilderCreationException(string typeName, string extraMessage = "") : base($"A nested call with `notNested: true`, or Either You forgot to call {typeName}.Dispose() of in the past.{extraMessage}") { diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index b1d4419e..1a7306cb 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -228,7 +228,7 @@ public void Append(ReadOnlySpan value) { Grow(value.Length); } - + value.CopyTo(buffer.AsSpan(index)); index += value.Length; } @@ -578,10 +578,6 @@ static void ThrowFormatException() { throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } - private static void FormatError() - { - throw new FormatException("Input string was not in a correct format."); - } void AppendFormatInternal(T arg, int width, ReadOnlySpan format, string argName) { @@ -648,19 +644,6 @@ static void ThrowNestedException() throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); } - void AppendFormatInternal(T arg1, ReadOnlySpan format, string argName) - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(argName); - } - } - index += written; - } - /// /// Register custom formatter /// diff --git a/src/ZString/NestedStringBuilderCreationException.cs b/src/ZString/NestedStringBuilderCreationException.cs index 4f263d94..ba88121f 100644 --- a/src/ZString/NestedStringBuilderCreationException.cs +++ b/src/ZString/NestedStringBuilderCreationException.cs @@ -5,10 +5,6 @@ namespace Cysharp.Text // Currently, this class is internals. internal class NestedStringBuilderCreationException : InvalidOperationException { - private NestedStringBuilderCreationException() - { - } - internal protected NestedStringBuilderCreationException(string typeName, string extraMessage = "") : base($"A nested call with `notNested: true`, or Either You forgot to call {typeName}.Dispose() of in the past.{extraMessage}") { diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index b1d4419e..1a7306cb 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -228,7 +228,7 @@ public void Append(ReadOnlySpan value) { Grow(value.Length); } - + value.CopyTo(buffer.AsSpan(index)); index += value.Length; } @@ -578,10 +578,6 @@ static void ThrowFormatException() { throw new FormatException("Index (zero based) must be greater than or equal to zero and less than the size of the argument list."); } - private static void FormatError() - { - throw new FormatException("Input string was not in a correct format."); - } void AppendFormatInternal(T arg, int width, ReadOnlySpan format, string argName) { @@ -648,19 +644,6 @@ static void ThrowNestedException() throw new NestedStringBuilderCreationException(nameof(Utf16ValueStringBuilder)); } - void AppendFormatInternal(T arg1, ReadOnlySpan format, string argName) - { - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out var written, format)) - { - Grow(written); - if (!FormatterCache.TryFormatDelegate(arg1, buffer.AsSpan(index), out written, format)) - { - ThrowArgumentException(argName); - } - } - index += written; - } - /// /// Register custom formatter /// From 6f32760dd59cf856cf97e0472fd6e4c4589d7e32 Mon Sep 17 00:00:00 2001 From: udaken <7896698+udaken@users.noreply.github.com> Date: Sat, 29 May 2021 21:04:07 +0900 Subject: [PATCH 130/139] Improved performance of Utf16ValueStringBuilder.AppendFormat on Slow Span Environment --- .../Utf16ValueStringBuilder.AppendFormat.cs | 128 +++++++++--------- .../ZString/Utf16ValueStringBuilder.cs | 38 ++++++ .../Assets/Scripts/ZString/ZStringWriter.cs | 2 +- .../Utf16ValueStringBuilder.AppendFormat.cs | 128 +++++++++--------- .../Utf16ValueStringBuilder.AppendFormat.tt | 8 +- src/ZString/Utf16ValueStringBuilder.cs | 38 ++++++ src/ZString/ZStringWriter.cs | 2 +- 7 files changed, 210 insertions(+), 134 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 717464b7..9531e7d5 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -27,7 +27,7 @@ public void AppendFormat(string format, T1 arg1) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -35,7 +35,7 @@ public void AppendFormat(string format, T1 arg1) else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -57,7 +57,7 @@ public void AppendFormat(string format, T1 arg1) if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -74,7 +74,7 @@ public void AppendFormat(string format, T1 arg1) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -101,7 +101,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -109,7 +109,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -134,7 +134,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -151,7 +151,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -178,7 +178,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -186,7 +186,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -214,7 +214,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -231,7 +231,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -258,7 +258,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -266,7 +266,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -297,7 +297,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -314,7 +314,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -341,7 +341,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -349,7 +349,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -383,7 +383,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -400,7 +400,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -427,7 +427,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -435,7 +435,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -472,7 +472,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -489,7 +489,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -516,7 +516,7 @@ public void AppendFormat(string format, T1 arg1, T2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -524,7 +524,7 @@ public void AppendFormat(string format, T1 arg1, T2 else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -564,7 +564,7 @@ public void AppendFormat(string format, T1 arg1, T2 if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -581,7 +581,7 @@ public void AppendFormat(string format, T1 arg1, T2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -608,7 +608,7 @@ public void AppendFormat(string format, T1 arg1, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -616,7 +616,7 @@ public void AppendFormat(string format, T1 arg1, else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -659,7 +659,7 @@ public void AppendFormat(string format, T1 arg1, if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -676,7 +676,7 @@ public void AppendFormat(string format, T1 arg1, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -703,7 +703,7 @@ public void AppendFormat(string format, T1 a if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -711,7 +711,7 @@ public void AppendFormat(string format, T1 a else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -757,7 +757,7 @@ public void AppendFormat(string format, T1 a if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -774,7 +774,7 @@ public void AppendFormat(string format, T1 a var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -801,7 +801,7 @@ public void AppendFormat(string format, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -809,7 +809,7 @@ public void AppendFormat(string format, else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -858,7 +858,7 @@ public void AppendFormat(string format, if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -875,7 +875,7 @@ public void AppendFormat(string format, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -902,7 +902,7 @@ public void AppendFormat(string fo if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -910,7 +910,7 @@ public void AppendFormat(string fo else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -962,7 +962,7 @@ public void AppendFormat(string fo if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -979,7 +979,7 @@ public void AppendFormat(string fo var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1006,7 +1006,7 @@ public void AppendFormat(stri if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1014,7 +1014,7 @@ public void AppendFormat(stri else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -1069,7 +1069,7 @@ public void AppendFormat(stri if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -1086,7 +1086,7 @@ public void AppendFormat(stri var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1113,7 +1113,7 @@ public void AppendFormat if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1121,7 +1121,7 @@ public void AppendFormat else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -1179,7 +1179,7 @@ public void AppendFormat if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -1196,7 +1196,7 @@ public void AppendFormat var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1223,7 +1223,7 @@ public void AppendFormat 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1336,7 +1336,7 @@ public void AppendFormat 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1452,7 +1452,7 @@ public void AppendFormat 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index b1d4419e..81c8ecf7 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -220,6 +220,44 @@ public void AppendLine(string value) AppendLine(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string value, int startIndex, int count) + { + if (value == null) + { + if (startIndex == 0 && count == 0) + { + return; + } + else + { + throw new ArgumentNullException(nameof(value)); + } + } + +#if UNITY_2018_3_OR_NEWER + if (buffer.Length - index < count) + { + Grow(count); + } + value.CopyTo(startIndex, buffer, index, count); + index += count; +#else + Append(value.AsSpan(startIndex, count)); +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char[] value, int startIndex, int charCount) + { + if (buffer.Length - index < charCount) + { + Grow(charCount); + } + Array.Copy(value, startIndex, buffer, index, charCount); + index += charCount; + } + /// Appends a contiguous region of arbitrary memory to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(ReadOnlySpan value) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs b/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs index 70580645..17f43b70 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/ZStringWriter.cs @@ -79,7 +79,7 @@ public override void Write(char[] buffer, int index, int count) } AssertNotDisposed(); - sb.Append(buffer.AsSpan(index, count)); + sb.Append(buffer, index, count); } public override void Write(string value) diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs index 717464b7..9531e7d5 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.cs @@ -27,7 +27,7 @@ public void AppendFormat(string format, T1 arg1) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -35,7 +35,7 @@ public void AppendFormat(string format, T1 arg1) else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -57,7 +57,7 @@ public void AppendFormat(string format, T1 arg1) if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -74,7 +74,7 @@ public void AppendFormat(string format, T1 arg1) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -101,7 +101,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -109,7 +109,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -134,7 +134,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -151,7 +151,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -178,7 +178,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -186,7 +186,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -214,7 +214,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -231,7 +231,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg3) var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -258,7 +258,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -266,7 +266,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -297,7 +297,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -314,7 +314,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 arg var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -341,7 +341,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -349,7 +349,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -383,7 +383,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -400,7 +400,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2, T3 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -427,7 +427,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -435,7 +435,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -472,7 +472,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -489,7 +489,7 @@ public void AppendFormat(string format, T1 arg1, T2 arg2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -516,7 +516,7 @@ public void AppendFormat(string format, T1 arg1, T2 if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -524,7 +524,7 @@ public void AppendFormat(string format, T1 arg1, T2 else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -564,7 +564,7 @@ public void AppendFormat(string format, T1 arg1, T2 if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -581,7 +581,7 @@ public void AppendFormat(string format, T1 arg1, T2 var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -608,7 +608,7 @@ public void AppendFormat(string format, T1 arg1, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -616,7 +616,7 @@ public void AppendFormat(string format, T1 arg1, else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -659,7 +659,7 @@ public void AppendFormat(string format, T1 arg1, if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -676,7 +676,7 @@ public void AppendFormat(string format, T1 arg1, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -703,7 +703,7 @@ public void AppendFormat(string format, T1 a if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -711,7 +711,7 @@ public void AppendFormat(string format, T1 a else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -757,7 +757,7 @@ public void AppendFormat(string format, T1 a if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -774,7 +774,7 @@ public void AppendFormat(string format, T1 a var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -801,7 +801,7 @@ public void AppendFormat(string format, if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -809,7 +809,7 @@ public void AppendFormat(string format, else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -858,7 +858,7 @@ public void AppendFormat(string format, if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -875,7 +875,7 @@ public void AppendFormat(string format, var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -902,7 +902,7 @@ public void AppendFormat(string fo if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -910,7 +910,7 @@ public void AppendFormat(string fo else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -962,7 +962,7 @@ public void AppendFormat(string fo if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -979,7 +979,7 @@ public void AppendFormat(string fo var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1006,7 +1006,7 @@ public void AppendFormat(stri if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1014,7 +1014,7 @@ public void AppendFormat(stri else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -1069,7 +1069,7 @@ public void AppendFormat(stri if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -1086,7 +1086,7 @@ public void AppendFormat(stri var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1113,7 +1113,7 @@ public void AppendFormat if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -1121,7 +1121,7 @@ public void AppendFormat else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -1179,7 +1179,7 @@ public void AppendFormat if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -1196,7 +1196,7 @@ public void AppendFormat var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1223,7 +1223,7 @@ public void AppendFormat 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1336,7 +1336,7 @@ public void AppendFormat 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } @@ -1452,7 +1452,7 @@ public void AppendFormat 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } diff --git a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt index 60a0fdcb..d59ccb2a 100644 --- a/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt +++ b/src/ZString/Utf16/Utf16ValueStringBuilder.AppendFormat.tt @@ -35,7 +35,7 @@ namespace Cysharp.Text if (i != format.Length && format[i + 1] == '{') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '{' copyFrom = i; continue; @@ -43,7 +43,7 @@ namespace Cysharp.Text else { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); } // try to find range @@ -67,7 +67,7 @@ namespace Cysharp.Text if (i + 1 < format.Length && format[i + 1] == '}') { var size = i - copyFrom; - Append(format.AsSpan(copyFrom, size)); + Append(format, copyFrom, size); i = i + 1; // skip escaped '}' copyFrom = i; continue; @@ -84,7 +84,7 @@ namespace Cysharp.Text var copyLength = format.Length - copyFrom; if (copyLength > 0) { - Append(format.AsSpan(copyFrom, copyLength)); + Append(format, copyFrom, copyLength); } } } diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index b1d4419e..81c8ecf7 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -220,6 +220,44 @@ public void AppendLine(string value) AppendLine(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string value, int startIndex, int count) + { + if (value == null) + { + if (startIndex == 0 && count == 0) + { + return; + } + else + { + throw new ArgumentNullException(nameof(value)); + } + } + +#if UNITY_2018_3_OR_NEWER + if (buffer.Length - index < count) + { + Grow(count); + } + value.CopyTo(startIndex, buffer, index, count); + index += count; +#else + Append(value.AsSpan(startIndex, count)); +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char[] value, int startIndex, int charCount) + { + if (buffer.Length - index < charCount) + { + Grow(charCount); + } + Array.Copy(value, startIndex, buffer, index, charCount); + index += charCount; + } + /// Appends a contiguous region of arbitrary memory to this instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(ReadOnlySpan value) diff --git a/src/ZString/ZStringWriter.cs b/src/ZString/ZStringWriter.cs index 70580645..17f43b70 100644 --- a/src/ZString/ZStringWriter.cs +++ b/src/ZString/ZStringWriter.cs @@ -79,7 +79,7 @@ public override void Write(char[] buffer, int index, int count) } AssertNotDisposed(); - sb.Append(buffer.AsSpan(index, count)); + sb.Append(buffer, index, count); } public override void Write(string value) From 07c4342bcd7d344ed2afd16ad38f8b6d5494c048 Mon Sep 17 00:00:00 2001 From: udaken <7896698+udaken@users.noreply.github.com> Date: Mon, 14 Jun 2021 00:08:46 +0900 Subject: [PATCH 131/139] Improved performance of Utf16ValueStringBuilder.Append/Utf8ValueStringBuilder.Append on Slow Span Environment --- .../Assets/Scripts/ZString/Utf16ValueStringBuilder.cs | 4 ++-- .../Assets/Scripts/ZString/Utf8ValueStringBuilder.cs | 2 +- src/ZString/Utf16ValueStringBuilder.cs | 4 ++-- src/ZString/Utf8ValueStringBuilder.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 81c8ecf7..8f410ce5 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -200,7 +200,7 @@ public void AppendLine(char value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { -#if UNITY_2018_3_OR_NEWER +#if UNITY_2018_3_OR_NEWER || NETSTANDARD2_0 if (buffer.Length - index < value.Length) { Grow(value.Length); @@ -235,7 +235,7 @@ public void Append(string value, int startIndex, int count) } } -#if UNITY_2018_3_OR_NEWER +#if UNITY_2018_3_OR_NEWER || NETSTANDARD2_0 if (buffer.Length - index < count) { Grow(count); diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index 0c66add1..5cac226b 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -228,7 +228,7 @@ public void AppendLine(char value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { -#if UNITY_2018_3_OR_NEWER +#if UNITY_2018_3_OR_NEWER || NETSTANDARD2_0 var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); if (buffer.Length - index < maxLen) { diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 81c8ecf7..8f410ce5 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -200,7 +200,7 @@ public void AppendLine(char value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { -#if UNITY_2018_3_OR_NEWER +#if UNITY_2018_3_OR_NEWER || NETSTANDARD2_0 if (buffer.Length - index < value.Length) { Grow(value.Length); @@ -235,7 +235,7 @@ public void Append(string value, int startIndex, int count) } } -#if UNITY_2018_3_OR_NEWER +#if UNITY_2018_3_OR_NEWER || NETSTANDARD2_0 if (buffer.Length - index < count) { Grow(count); diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index 0c66add1..5cac226b 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -228,7 +228,7 @@ public void AppendLine(char value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { -#if UNITY_2018_3_OR_NEWER +#if UNITY_2018_3_OR_NEWER || NETSTANDARD2_0 var maxLen = UTF8NoBom.GetMaxByteCount(value.Length); if (buffer.Length - index < maxLen) { From b6a45c9b096c3b42d88c0a9a342597a55394ff54 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Nov 2021 11:21:33 +0000 Subject: [PATCH 132/139] feat: Update package.json to 2.4.3 --- src/ZString.Unity/Assets/Scripts/ZString/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json b/src/ZString.Unity/Assets/Scripts/ZString/package.json index bb2dd340..c81a2589 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/package.json +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json @@ -1,7 +1,7 @@ { "name": "com.cysharp.zstring", "displayName": "ZString", - "version": "2.4.2", + "version": "2.4.3", "unity": "2018.4", "description": "Zero Allocation StringBuilder for .NET Core and Unity.", "keywords": [ From 3c25e7a9b3d1e16977856fb8104f7b49a8a70e8d Mon Sep 17 00:00:00 2001 From: axunonb Date: Tue, 2 Nov 2021 22:14:04 +0100 Subject: [PATCH 133/139] Squashed commit of the following: commit a8dec64b7a6090cc4e4c3f491e3475feffd567b1 Merge: ebb820c c4f0115 Author: axunonb Date: Tue Nov 2 21:55:35 2021 +0100 Merge branch 'axuno:main' into main commit c4f0115b4e7873c2aaa5f839ab807c8a7c2bea6b Author: axunonb Date: Tue Nov 2 21:54:46 2021 +0100 Delete .github/workflows directory commit 3283ba98be417b2668d6226af7a36259d352f73d Author: axunonb Date: Tue Nov 2 17:05:09 2021 +0100 Remove demo projects commit 0ebf3f411ebb4e492f4e30912f3f681b3900e36a Author: axunonb Date: Tue Nov 2 16:30:42 2021 +0100 Corrected path to test project commit a9a79d1e9cc625907e494e0693d973b38c3e5c4a Author: axunonb Date: Tue Nov 2 16:22:48 2021 +0100 Add AltCover to test commit 608533fa43ffa504b2731e0fd6a77025e14d20f9 Author: axunonb Date: Tue Nov 2 16:07:01 2021 +0100 Update build.yml commit 3005692bda97fb669cf5b1c08a1e941062c78965 Author: axunonb Date: Tue Nov 2 15:00:06 2021 +0100 Update build.yml commit 4683d5925b11f4b102c61bbd5dbd81714b5d9134 Author: axunonb Date: Tue Nov 2 14:23:29 2021 +0100 Update build.yml commit d3f9b68eb5571ac8a6b866a29e65e29a79b7b1e1 Author: axunonb Date: Tue Nov 2 14:19:05 2021 +0100 Update build.yml commit 4ac19ea1d3715bf5c88ae86a52d5eb1fca074a1a Author: axunonb Date: Tue Nov 2 14:11:42 2021 +0100 Update build.yml commit ef76dba3d489b12258bfc14a32b6dffd18124f20 Author: axunonb Date: Tue Nov 2 14:08:13 2021 +0100 Update build.yml commit e2406b464166f33640b0ab1dff0739b9b69c96ae Author: axunonb Date: Tue Nov 2 14:01:07 2021 +0100 Update build.yml commit adee45a7af07fcd3f06c85c24b6e34f0da933432 Author: axunonb Date: Tue Nov 2 14:00:40 2021 +0100 Update build.yml commit 5464bb9dd8b589cee3fa93ece66e7361fbd520eb Author: axunonb Date: Tue Nov 2 13:53:50 2021 +0100 Create build.yml commit ebb820c1ff3035214c5169b2943edb41d881e6b8 Merge: 365bbd0 ca28b30 Author: axunonb Date: Thu Oct 21 10:06:49 2021 +0200 Merge branch 'axuno:main' into main commit ca28b3005ce8b9132a892e6757c0ebe6584afe8d Author: axunonb Date: Thu Oct 21 10:05:03 2021 +0200 Backport fixes from v3 (#213) Bumped version to 2.7.1 Back-ported bug fixes from v3.0.0-alpha: #179 - Corrected DualFromZeroToTwo plural rule #211 . Illegal placeholder characters that are not 8-bit, will no more throw unexpected ThrowByteOverflowException commit 365bbd08a83b9d71acb4775ee54a6c0177a23040 Author: axunonb Date: Thu Oct 21 09:16:12 2021 +0200 Bumped version to 2.7.1 Backported bug fixes from v3.0.0-alpha: #179 - Corrected DualFromZeroToTwo plural rule #211 . Illegal placeholder characters that are not 8-bit, will no more throw unexpected ThrowByteOverflowException commit 3165fc7226ff5659da44aa36bf678fb9ec34d942 Author: axunonb Date: Thu Oct 21 08:03:32 2021 +0200 Updated NuGet secure key commit 8169585baf5a3d1c6da6b5f2bb7672b126c14e60 Author: axunonb Date: Sun Sep 5 23:09:38 2021 +0200 Update README.md commit 1e09b6a1548c22375e29879f8c943edaa6490f25 Author: axunonb Date: Mon Aug 30 01:52:50 2021 +0200 Update README.md commit 8954f3ec76e3554523c2e304d121cffc4fa25350 Author: axunonb Date: Mon Aug 30 01:51:32 2021 +0200 Update README.md commit a16b01c43438dd62aba5248ab28fc4754441f8f4 Author: axunonb Date: Tue Jun 15 00:06:03 2021 +0200 Update README.md commit d9462f586726d14b50198ee255bde2e38fc54813 Author: axunonb Date: Tue Jun 15 00:05:17 2021 +0200 Update README.md --- CHANGES.md | 2 +- appveyor.yml | 1 - src/SmartFormat/SmartFormat.csproj | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3ef3501c..f7b39145 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,7 @@ Latest Changes ==== -What's new in v3.0.0-alpha.3 +What's new in v3.0.0-alpha.4 ==== ### 1. Significant boost in performance diff --git a/appveyor.yml b/appveyor.yml index 96957387..0faf552e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -62,4 +62,3 @@ for: test_script: - dotnet test --no-build --framework net5.0 SmartFormat.sln /p:configuration=release /p:AltCover=true /p:AltCoverXmlReport="coverage.xml" /p:AltCover=true /p:AltCoverStrongNameKey="..\SmartFormat\SmartFormat.snk" /p:AltCoverAssemblyExcludeFilter="SmartFormat.Tests|NUnit3.TestAdapter" /p:AltCoverLineCover="true" - bash <(curl -s https://codecov.io/bash) -f ./SmartFormat.Tests/coverage.net5.0.xml -n net5.0linux - diff --git a/src/SmartFormat/SmartFormat.csproj b/src/SmartFormat/SmartFormat.csproj index be921ff9..44ecc3af 100644 --- a/src/SmartFormat/SmartFormat.csproj +++ b/src/SmartFormat/SmartFormat.csproj @@ -10,7 +10,7 @@ SmartFormat.snk true SmartFormat.NET - See the change log with for details of this release: + See the change log for details of this release: https://github.com/axuno/SmartFormat/blob/master/CHANGES.md https://github.com/axuno/SmartFormat From ea9f7a8493f94dadf7bca661d4e012451d7abdb9 Mon Sep 17 00:00:00 2001 From: axunonb Date: Sun, 19 Dec 2021 00:42:10 +0100 Subject: [PATCH 134/139] Initial commit --- .../PersistentVariableSourceTests.cs | 281 ++++++++++++++++++ .../Extensions/VariablesGroupTests.cs | 168 +++++++++++ .../Pooling/ConcurrentPoolingTests.cs | 12 +- .../PersistentVariables.cs | 78 +++++ .../PersistentVariables/VariableInterfaces.cs | 37 +++ .../VariableNameValuePair.cs | 21 ++ .../PersistentVariables/VariablesGroup.cs | 188 ++++++++++++ .../Extensions/PersistentVariablesSource.cs | 216 ++++++++++++++ 8 files changed, 991 insertions(+), 10 deletions(-) create mode 100644 src/SmartFormat.Tests/Extensions/PersistentVariableSourceTests.cs create mode 100644 src/SmartFormat.Tests/Extensions/VariablesGroupTests.cs create mode 100644 src/SmartFormat/Extensions/PersistentVariables/PersistentVariables.cs create mode 100644 src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs create mode 100644 src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs create mode 100644 src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs create mode 100644 src/SmartFormat/Extensions/PersistentVariablesSource.cs diff --git a/src/SmartFormat.Tests/Extensions/PersistentVariableSourceTests.cs b/src/SmartFormat.Tests/Extensions/PersistentVariableSourceTests.cs new file mode 100644 index 00000000..3d616440 --- /dev/null +++ b/src/SmartFormat.Tests/Extensions/PersistentVariableSourceTests.cs @@ -0,0 +1,281 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using SmartFormat.Core.Formatting; +using SmartFormat.Core.Settings; +using SmartFormat.Extensions; +using SmartFormat.Extensions.PersistentVariables; + +namespace SmartFormat.Tests.Extensions +{ + [TestFixture] + public class PersistentVariableSourceTests + { + [Test] + public void Is_Not_ReadOnly() + { + Assert.That(new PersistentVariablesSource().IsReadOnly, Is.False); + } + + [Test] + public void Add_And_Get_Items() + { + const string groupName1 = "global"; + const string groupName2 = "secret"; + + var pvs = new PersistentVariablesSource(); + var vg1 = new VariablesGroup(); + var vg2 = new VariablesGroup(); + + pvs.Add(groupName1, vg1); + pvs[groupName2] = vg2; + + Assert.That(pvs.Count, Is.EqualTo(2)); + Assert.That(pvs[groupName1], Is.EqualTo(vg1)); + Assert.That(pvs[groupName2], Is.EqualTo(vg2)); + Assert.That(pvs.Keys.Count, Is.EqualTo(2)); + Assert.That(pvs.Keys.Contains(groupName1)); + Assert.That(pvs.Values.Count, Is.EqualTo(2)); + Assert.That(pvs.Values.Contains(vg1)); + Assert.That(pvs.Values.Contains(vg2)); + Assert.That(pvs.ContainsKey(groupName2)); + Assert.That(pvs.TryGetValue(groupName1, out _), Is.True); + Assert.That(pvs.TryGetValue(groupName1 + "False", out _), Is.False); + } + + [Test] + public void Add_Key_Value_Pair() + { + var pvs = new PersistentVariablesSource(); + var kvp = new KeyValuePair("theKey", new VariablesGroup()); + pvs.Add(kvp); + + Assert.That(pvs.Contains(new KeyValuePair(kvp.Key, kvp.Value))); + } + + [Test] + public void KeyValuePairs_By_Enumerators() + { + var pvs = new PersistentVariablesSource(); + var kvp = new KeyValuePair("theKey", new VariablesGroup()); + pvs.Add(kvp); + var kvpFromEnumerator = pvs.FirstOrDefault(keyValuePair => keyValuePair.Key.Equals("theKey")); + + // Test GetEnumerator() + foreach (var keyValuePair in pvs) + { + Assert.That(keyValuePair, Is.EqualTo(kvp)); + } + + // Test IEnumerator> + Assert.That(kvpFromEnumerator, Is.EqualTo(kvp)); + } + + [Test] + public void Add_Item_With_Illegal_Name_Should_Throw() + { + var pvs = new PersistentVariablesSource(); + var vg = new VariablesGroup(); + + // Name must not be empty + Assert.That(code: () => vg.Add(string.Empty, new IntVariable(1)), Throws.ArgumentException); + Assert.That(code: () => pvs.Add(string.Empty, vg), Throws.ArgumentException); + } + + [Test] + public void Remove_Item() + { + var pvs = new PersistentVariablesSource(); + var kvp = new KeyValuePair("theKey", new VariablesGroup()); + pvs.Add(kvp); + pvs.Remove(kvp); + + Assert.That(pvs.Count, Is.EqualTo(0)); + Assert.That(pvs.Remove("non-existent"), Is.EqualTo(false)); + } + + [Test] + public void Remove_Key_Value_Pair() + { + var pvs = new PersistentVariablesSource { { "global", new VariablesGroup() } }; + pvs.Remove("global"); + + Assert.That(pvs.Count, Is.EqualTo(0)); + Assert.That(pvs.Remove("non-existent"), Is.EqualTo(false)); + } + + [Test] + public void Clear_All_Items() + { + var pvs = new PersistentVariablesSource(); + var kvp = new KeyValuePair("theKey", new VariablesGroup()); + pvs.Add(kvp); + pvs.Clear(); + + Assert.That(pvs.Count, Is.EqualTo(0)); + } + + [Test] + public void Copy_To_Array() + { + var pvs = new PersistentVariablesSource(); + var kvp1 = new KeyValuePair("key1", new VariablesGroup()); + var kvp2 = new KeyValuePair("key2", new VariablesGroup()); + pvs.Add(kvp1); + pvs.Add(kvp2); + + var array = new KeyValuePair[pvs.Count]; + pvs.CopyTo(array, 0); + + Assert.That(pvs.Count, Is.EqualTo(array.Length)); + for (var i = 0; i < array.Length; i++) + { + Assert.That(pvs.ContainsKey(array[i].Key)); + } + } + + [Test] + public void Shallow_Copy() + { + var pvs = new PersistentVariablesSource(); + + var kvp1 = new KeyValuePair("theKey1", new ObjectVariable("123")); + var kvp2 = new KeyValuePair("theKey2", new FloatVariable(987.654f)); + + var vg1 = new VariablesGroup { kvp1 }; + var vg2 = new VariablesGroup { kvp2 }; + + pvs.Add(vg1.First().Key, vg1); + pvs.Add(vg2.First().Key, vg2); + + var pvsCopy = pvs.Clone(); + + Assert.That(pvsCopy.Count, Is.EqualTo(pvs.Count)); + Assert.That(pvsCopy.Values, Is.EquivalentTo(pvs.Values)); + Assert.That(pvsCopy.Keys, Is.EquivalentTo(pvs.Keys)); + } + + [Test] + public void Use_Globals_Without_Args_To_Formatter() + { + // The top container + // It gets its name later, when being added to the PersistentVariablesSource + var varGrp = new VariablesGroup(); + + // Add a (nested) VariablesGroup named 'group' to the top container + varGrp.Add("group", new VariablesGroup + { + // Add variables to the nested group + { "groupString", new StringVariable("groupStringValue") }, + { "groupDateTime", new Variable(new DateTime(2024, 12, 31)) } + }); + // Add more variables to the top group container + varGrp.Add(new KeyValuePair("topInteger", new IntVariable(12345))); + var stringVar = new StringVariable("topStringValue"); + varGrp.Add("topString", stringVar); + + // The formatter for persistent variables requires only 2 extensions + var smart = new SmartFormatter(); + smart.FormatterExtensions.Add(new DefaultFormatter()); + // Add as the first in the source extensions list + var pvs = new PersistentVariablesSource + { + // Here, the top container gets its name + { "global", varGrp } + }; + smart.AddExtensions(0, pvs); + + // Act + // Note: We don't need args to the formatter for globals + var globalGroup = smart.Format(CultureInfo.InvariantCulture, + "{global.group.groupString} {global.group.groupDateTime:'groupDateTime='yyyy-MM-dd}"); + var topInteger = smart.Format("{global.topInteger}"); + var topString = smart.Format("{global.topString}"); + + // Assert + Assert.That(globalGroup, Is.EqualTo("groupStringValue groupDateTime=2024-12-31")); + Assert.That(topString, Is.EqualTo(stringVar.ToString())); + Assert.That(topInteger, Is.EqualTo("12345")); + } + + [Test] + public void NonExisting_GroupVariable_Should_Throw() + { + var varGrp = new VariablesGroup { { "existing", new StringVariable("existing-value") } }; + + var smart = new SmartFormatter(); + smart.FormatterExtensions.Add(new DefaultFormatter()); + smart.AddExtensions(0, new PersistentVariablesSource()); + var resultExisting = smart.Format("{existing}", varGrp); + + Assert.That(resultExisting, Is.EqualTo("existing-value")); + Assert.That(code: () => smart.Format("{non-existing}", varGrp), + Throws.InstanceOf().And.Message.Contains("non-existing")); + } + + [Test] + public void PersistentVariablesSource_NameGroupPair() + { + var pvs = new PersistentVariablesSource.NameGroupPair("theName", + new VariablesGroup + { new KeyValuePair("varName", new IntVariable(123)) }); + + Assert.That(pvs.Name, Is.EqualTo("theName")); + Assert.That(pvs.Group.ContainsKey("varName"), Is.True); + } + + [Test] + public void Format_Args_Should_Override_Persistent_Vars() + { + const string formatString = "{global.theVariable}"; + + // Setup PersistentVariablesSource + + var persistentGrp = new VariablesGroup + { { "theVariable", new StringVariable("val-from-persistent-source") } }; + + var smart = new SmartFormatter(); + smart.FormatterExtensions.Add(new DefaultFormatter()); + smart.AddExtensions(0, new PersistentVariablesSource {{"global", persistentGrp}}); + + // Setup equivalent VariablesGroup to use as an argument to Smart.Format(...) + + var argumentGrp = new VariablesGroup + { { "global", new VariablesGroup { { "theVariable", new StringVariable("val-from-argument") } } } }; + + // Arguments override PersistentVariablesSource + var argumentResult = smart.Format(formatString, argumentGrp); + // Without arguments, the variable from PersistentVariablesSource is used + var persistentResult = smart.Format(formatString); + + Assert.That(argumentResult, Is.EqualTo("val-from-argument")); + Assert.That(persistentResult, Is.EqualTo("val-from-persistent-source")); + } + + [Test] + public void Parallel_Load_By_Adding_Variables_To_Source() + { + // Switch to thread safety - otherwise the test would throw an InvalidOperationException + const bool currentThreadSafeMode = true; + var savedIsThreadSafeMode = SmartSettings.IsThreadSafeMode; + SmartSettings.IsThreadSafeMode = currentThreadSafeMode; + + var pvs = new PersistentVariablesSource { { "global", new VariablesGroup() } }; + var options = new ParallelOptions { MaxDegreeOfParallelism = 10 }; + + Assert.That(code: () => + Parallel.For(0L, 1000, options, (i, loopState) => + { + pvs["global"].Add($"{i:0000}", new IntVariable((int)i)); + }), Throws.Nothing); + Assert.That(pvs["global"].Count, Is.EqualTo(1000)); + + // Restore to saved value + SmartSettings.IsThreadSafeMode = savedIsThreadSafeMode; + } + } +} diff --git a/src/SmartFormat.Tests/Extensions/VariablesGroupTests.cs b/src/SmartFormat.Tests/Extensions/VariablesGroupTests.cs new file mode 100644 index 00000000..8f13ba1b --- /dev/null +++ b/src/SmartFormat.Tests/Extensions/VariablesGroupTests.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NUnit.Framework; +using SmartFormat.Core.Formatting; +using SmartFormat.Extensions; +using SmartFormat.Extensions.PersistentVariables; + +namespace SmartFormat.Tests.Extensions +{ + [TestFixture] + public class VariablesGroupTests + { + [Test] + public void Is_Not_ReadOnly() + { + Assert.That(new VariablesGroup().IsReadOnly, Is.False); + } + + [Test] + public void Add_And_Get_Items() + { + const string var1Name = "var1name"; + const string var2Name = "var2name"; + const string var3Name = "var3name"; + + var var1 = new IntVariable(1234); + var var2 = new StringVariable("theValue"); + var var3 = new BoolVariable(true); + + var vg = new VariablesGroup + { + { var1Name, var1 }, + new KeyValuePair(var2Name, var2) + }; + vg[var3Name] = var3; + + Assert.That(vg.Count, Is.EqualTo(3)); + Assert.That((int) vg[var1Name].GetValue()!, Is.EqualTo(1234)); + Assert.That((string) vg[var2Name].GetValue()!, Is.EqualTo("theValue")); + Assert.That(vg.Keys.Count, Is.EqualTo(3)); + Assert.That(vg.Keys.Contains(var1Name)); + Assert.That(vg.Values.Count, Is.EqualTo(3)); + Assert.That(vg.Values.Contains(var1)); + Assert.That(vg.Values.Contains(var2)); + Assert.That(vg.Values.Contains(var3)); + Assert.That(vg.ContainsKey(var2Name)); + Assert.That(vg.TryGetValue(var1Name + "False", out _), Is.False); + } + + [Test] + public void Add_Key_Value_Pair() + { + var vg = new VariablesGroup(); + var kvp = new KeyValuePair("theKey", new IntVariable(9876)); + vg.Add(kvp); + + Assert.That(vg.Contains(new KeyValuePair(kvp.Key, kvp.Value))); + } + + [Test] + public void KeyValuePairs_By_Enumerators() + { + var vg = new VariablesGroup(); + var kvp = new KeyValuePair("theKey", new IntVariable(9876)); + vg.Add(kvp); + var kvpFromEnumerator = vg.FirstOrDefault(keyValuePair => keyValuePair.Key.Equals("theKey")); + + // Test GetEnumerator() + foreach (var keyValuePair in vg) + { + Assert.That(keyValuePair, Is.EqualTo(kvp)); + } + + // Test IEnumerator> + Assert.That(kvpFromEnumerator, Is.EqualTo(kvp)); + } + + [Test] + public void Add_Item_With_Illegal_Name_Should_Throw() + { + var vg = new VariablesGroup(); + + // Name must not be empty + Assert.That(code: () => vg.Add(string.Empty, new IntVariable(1)), Throws.ArgumentException); + } + + [Test] + public void Remove_Item() + { + var vg = new VariablesGroup(); + var kvp = new KeyValuePair("theKey", new IntVariable(12)); + vg.Add(kvp); + vg.Remove(kvp); + + Assert.That(vg.Count, Is.EqualTo(0)); + Assert.That(vg.Remove("non-existent"), Is.EqualTo(false)); + } + + [Test] + public void Remove_Key_Value_Pair() + { + var vg = new VariablesGroup { { "theKey", new IntVariable(12) } }; + vg.Remove("theKey"); + + Assert.That(vg.Count, Is.EqualTo(0)); + Assert.That(vg.Remove("non-existent"), Is.EqualTo(false)); + } + + [Test] + public void Clear_All_Items() + { + var vg = new VariablesGroup(); + var kvp = new KeyValuePair("theKey", new IntVariable(135)); + vg.Add(kvp); + vg.Clear(); + + Assert.That(vg.Count, Is.EqualTo(0)); + } + + [Test] + public void Copy_To_Array() + { + var vg = new VariablesGroup(); + var kvp1 = new KeyValuePair("theKey1", new IntVariable(135)); + var kvp2 = new KeyValuePair("theKey2", new IntVariable(987)); + vg.Add(kvp1); + vg.Add(kvp2); + + var array = new KeyValuePair[vg.Count]; + vg.CopyTo(array, 0); + + Assert.That(vg.Count, Is.EqualTo(array.Length)); + for (var i = 0; i < array.Length; i++) + { + Assert.That(vg.ContainsKey(array[i].Key)); + } + } + + [Test] + public void Shallow_Copy() + { + var vg = new VariablesGroup(); + var kvp1 = new KeyValuePair("theKey1", new ObjectVariable("123")); + var kvp2 = new KeyValuePair("theKey2", new FloatVariable(987.654f)); + vg.Add(kvp1); + vg.Add(kvp2); + var vgCopy = vg.Clone(); + + Assert.That(vgCopy.Count, Is.EqualTo(vg.Count)); + Assert.That(vgCopy.Values, Is.EquivalentTo(vg.Values)); + Assert.That(vgCopy.Keys, Is.EquivalentTo(vg.Keys)); + } + + [Test] + public void NameVariablePair_Test() + { + var nv = new NameVariablePair("theName", new IntVariable(1234)); + + Assert.That(nv.Name, Is.EqualTo("theName")); + Assert.That((int) nv.Variable.GetValue()!, Is.EqualTo(1234)); + Assert.That(nv.ToString(), Is.EqualTo("'theName' - 'System.Int32' - '1234'")); + } + } +} diff --git a/src/SmartFormat.Tests/Pooling/ConcurrentPoolingTests.cs b/src/SmartFormat.Tests/Pooling/ConcurrentPoolingTests.cs index b6769431..025bd176 100644 --- a/src/SmartFormat.Tests/Pooling/ConcurrentPoolingTests.cs +++ b/src/SmartFormat.Tests/Pooling/ConcurrentPoolingTests.cs @@ -73,33 +73,25 @@ public void Parallel_Load_On_Specialized_Pools() SmartSettings.IsThreadSafeMode = currentThreadSafeMode; ResetAllPools(currentThreadSafeMode); - // Used to make sure the counter is consecutive across threads, - // because Interlocked.Read/Write cannot. - Semaphore semaphoreObject = new (initialCount: 1, maximumCount: 1); const int maxLoops = 100; var options = new ParallelOptions { MaxDegreeOfParallelism = 10 }; SmartSettings.IsThreadSafeMode = true; var list = new ConcurrentBag(); - long counter = 1; Assert.That(() => Parallel.For(1L, maxLoops, options, (i, loopState) => { - semaphoreObject.WaitOne(); - var threadLocalCounter = counter++; - semaphoreObject.Release(); - using var formatParsed = new Parser().ParseFormat("Number: {0:00000}"); var smart = new SmartFormatter(); smart.AddExtensions(new DefaultSource()); smart.AddExtensions(new DefaultFormatter()); - list.Add(smart.Format(formatParsed, threadLocalCounter)); + list.Add(smart.Format(formatParsed, i)); }), Throws.Nothing); var result = list.OrderBy(e => e); long compareCounter = 1; - Assert.That(counter, Is.EqualTo(maxLoops)); + Assert.That(list.Count, Is.EqualTo(maxLoops - 1)); Assert.That(result.All(r => r == $"Number: {compareCounter++:00000}")); foreach (var p in GetAllPoolCounters()) diff --git a/src/SmartFormat/Extensions/PersistentVariables/PersistentVariables.cs b/src/SmartFormat/Extensions/PersistentVariables/PersistentVariables.cs new file mode 100644 index 00000000..c44f287a --- /dev/null +++ b/src/SmartFormat/Extensions/PersistentVariables/PersistentVariables.cs @@ -0,0 +1,78 @@ +// +// Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. +// Licensed under the MIT license. + +namespace SmartFormat.Extensions.PersistentVariables +{ + /// + /// Base class for all single source variables. + /// + /// The value type to store in this variable. + public class Variable : IVariable + { + /// + /// Creates a new variable. + /// + /// The value of the variable. + public Variable(T? value) + { + Value = value; + } + + /// + /// The value for the . + /// + public T? Value { get; set; } + + /// + public object? GetValue() => Value; + + /// + public override string ToString() => Value?.ToString() ?? string.Empty; + } + + /// + /// A that holds a single float value. + /// + public class FloatVariable : Variable + { + /// + public FloatVariable(float? value) : base(value) {} + } + + /// + /// A that holds a single string value. + /// + public class StringVariable : Variable + { + /// + public StringVariable(string? value) : base(value) {} + } + + /// + /// A that holds a single integer value. + /// + public class IntVariable : Variable + { + /// + public IntVariable(int? value) : base(value) {} + } + + /// + /// A that holds a single boolean value. + /// + public class BoolVariable : Variable + { + /// + public BoolVariable(bool? value) : base(value) {} + } + + /// + /// A that holds an instance. + /// + public class ObjectVariable : Variable + { + /// + public ObjectVariable(object? value) : base(value) {} + } +} diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs b/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs new file mode 100644 index 00000000..5b2865d4 --- /dev/null +++ b/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs @@ -0,0 +1,37 @@ +// +// Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. +// Licensed under the MIT license. + +using System; + +namespace SmartFormat.Extensions.PersistentVariables +{ + /// + /// Collection that contains . + /// + public interface IVariablesGroup + { + /// + /// Gets the variable with the matching key if one exists. + /// + /// The variable key or name to match. + /// The found variable or null if one could not be found. + /// true if a variable could be found or false if one could not. + bool TryGetValue(string key, out IVariable value); + } + + /// + /// Represents a variable that can be provided through a global or as a local + /// variable instead of as a SmartFormat argument. + /// A variable can be a single variable, in which case the value should be returned in + /// or a class with multiple variables which can then be further extracted as SmartFormat arguments. + /// + public interface IVariable + { + /// + /// Gets the boxed into a . + /// + /// The boxed into a . + object? GetValue(); + } +} diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs b/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs new file mode 100644 index 00000000..abd511d9 --- /dev/null +++ b/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs @@ -0,0 +1,21 @@ +// +// Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. +// Licensed under the MIT license. + +namespace SmartFormat.Extensions.PersistentVariables +{ + internal class NameVariablePair + { + public NameVariablePair(string name, IVariable variable) + { + Name = name; + Variable = variable; + } + + public string Name { get; } + + public IVariable Variable { get; } + + public override string ToString() => $"'{Name}' - '{Variable.GetValue()?.GetType()}' - '{Variable.GetValue()}'"; + } +} \ No newline at end of file diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs new file mode 100644 index 00000000..e564303c --- /dev/null +++ b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using SmartFormat.Core.Settings; + +namespace SmartFormat.Extensions.PersistentVariables +{ + /// + /// A collection of s that can be used + /// as arguments to the Format(...) overloads of , + /// or it can be added to . + ///
+ /// Each instance of keeps its own collection. + /// + /// One instance of can be used from different threads, + /// if is when creating the instance. + /// + ///
+ public class VariablesGroup : IVariablesGroup, IVariable, IDictionary + { + private readonly IDictionary _variableLookup = SmartSettings.IsThreadSafeMode + ? new ConcurrentDictionary() + : new Dictionary(); + + /// + /// + /// Gets the number of s in the group. + /// + public int Count => _variableLookup.Count; + + /// + /// Gets an containing all the variable names. + /// + public ICollection Keys => _variableLookup.Keys; + + /// + /// Gets all the s for this group. + /// + public ICollection Values => _variableLookup.Values.Select(s => s.Variable).ToList(); + + /// + /// Implemented as part of IDictionary. Always returns . + /// + public bool IsReadOnly => false; + + /// + /// Gets or sets the with the specified name. + /// + /// The name of the . + /// The found variable. + /// Thrown if a variable with the specified name does not exist. + public IVariable this[string name] + { + get => _variableLookup[name].Variable; + set => Add(name, value); + } + + /// + public object GetValue() => this; + + /// + /// Gets the with the specified name from this . + /// + /// The name of the variable. + /// The variable that was found or default. + /// if a variable was found and if one could not. + public bool TryGetValue(string name, out IVariable value) + { + if (_variableLookup.TryGetValue(name, out var v)) + { + value = v.Variable; + return true; + } + + value = default!; + + return false; + } + + /// + /// Adds a new to the group. + /// + /// The name of the variable, must be unique and must only contain selector characters which are also accepted by the . + /// The variable to use when formatting. See also , , , , . + /// Thrown if is null or empty. + public void Add(string name, IVariable variable) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentException("Name must not be null or empty.", nameof(name)); + + var v = new NameVariablePair(name, variable); + _variableLookup.Add(name, v); + } + + /// + /// + /// + /// + public void Add(KeyValuePair item) => Add(item.Key, item.Value); + + /// + /// Removes an with the specified name. + /// + /// + /// if a variable with the specified name was removed, if one was not. + public bool Remove(string name) + { + if (_variableLookup.TryGetValue(name, out var v)) + { + return _variableLookup.Remove(name); + } + return false; + } + + /// + /// Removes an with the specified key. + /// + /// The item to be removed. Only the field will be considered. + /// if a variable with the specified name was removed, if one was not. + public bool Remove(KeyValuePair item) => Remove(item.Key); + + /// + /// Returns if a variable with the specified name exists. + /// + /// The variable name to check for. + /// if a matching variable could be found or if one could not. + public bool ContainsKey(string name) => _variableLookup.ContainsKey(name); + + /// + /// + /// + /// The item to check for. Both the Key and Value must match. + /// if a matching variable could be found or if one could not. + public bool Contains(KeyValuePair item) => TryGetValue(item.Key, out var v) && v == item.Value; + + /// + /// Copies the variables into an array starting at . + /// + /// The array to copy the variables into. + /// The index to start copying the items into. + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + foreach (var entry in _variableLookup) + array[arrayIndex++] = new KeyValuePair(entry.Key, entry.Value.Variable); + } + + /// + /// Creates a Shallow Copy of this . + /// + /// A Shallow Copy of this . + public VariablesGroup Clone() + { + var vg = new VariablesGroup(); + foreach (var entry in _variableLookup) + vg.Add(entry.Key, entry.Value.Variable); + + return vg; + } + + /// + /// + /// + /// The enumerator that can be used to iterate through all the variables. + IEnumerator> IEnumerable>.GetEnumerator() + { + return _variableLookup.Select(v => new KeyValuePair(v.Key, v.Value.Variable)).GetEnumerator(); + } + + /// + /// Returns an enumerator for all variables in this group. + /// + /// The enumerator that can be used to iterate through all the variables. + public IEnumerator GetEnumerator() + { + return _variableLookup.Select(v => new KeyValuePair(v.Key, v.Value.Variable)).GetEnumerator(); + } + + /// + /// Removes all variables in the group. + /// + public void Clear() + { + _variableLookup.Clear(); + } + } +} diff --git a/src/SmartFormat/Extensions/PersistentVariablesSource.cs b/src/SmartFormat/Extensions/PersistentVariablesSource.cs new file mode 100644 index 00000000..bb976502 --- /dev/null +++ b/src/SmartFormat/Extensions/PersistentVariablesSource.cs @@ -0,0 +1,216 @@ +// +// Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. +// Licensed under the MIT license. + +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using SmartFormat.Core.Extensions; +using SmartFormat.Core.Settings; +using SmartFormat.Extensions.PersistentVariables; + +namespace SmartFormat.Extensions +{ + /// + /// Provides (global) variables of type to the + /// that do not need to be passed in as arguments when formatting a string. + /// The smart string should take the placeholder format like {groupName.variableName}. + /// Note: s from args to SmartFormatter.Format(...) take precedence over . + /// + public class PersistentVariablesSource : ISource, IDictionary + { + internal class NameGroupPair + { + public NameGroupPair(string name, VariablesGroup group) + { + Name = name; + Group = group; + } + + public string Name { get; } + + public VariablesGroup Group { get; } + } + + private readonly IDictionary _groupLookup = SmartSettings.IsThreadSafeMode + ? new ConcurrentDictionary() + : new Dictionary(); + + /// + /// The number of stored variables. + /// + public int Count => _groupLookup.Values.Count; + + /// + /// Implemented as part of IDictionary. Will always return . + /// + public bool IsReadOnly => false; + + /// + /// Gets the names of stored s. + /// + public ICollection Keys => _groupLookup.Keys; + + /// + /// Gets the values of stored s. + /// + public ICollection Values => _groupLookup.Values.Select(k => k.Group).ToList(); + + /// + /// Gets the that matches . + /// + /// The name of the to return. + /// + public VariablesGroup this[string name] + { + get => _groupLookup[name].Group; + set => Add(name, value); + } + + /// + /// Returns if a could be found with a matching name, or if one could not. + /// + /// The name of the to find. + /// The found or default if one could not be found with a matching name. + /// if a group could be found or if one could not. + public bool TryGetValue(string name, out VariablesGroup value) + { + if (_groupLookup.TryGetValue(name, out var v)) + { + value = v.Group; + return true; + } + + value = default!; + return false; + } + + /// + /// Add a to the source. + /// + /// The name of the to add. + /// The to add. + /// Thrown if is null or empty. + public void Add(string name, VariablesGroup group) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentException("Name must not be null or empty.", nameof(name)); + + var pair = new NameGroupPair(name, group); + + _groupLookup[name] = pair; + } + + /// + public void Add(KeyValuePair item) => Add(item.Key, item.Value); + + /// + /// Removes the with the matching name. + /// + /// The name of the to remove. + /// if a with a matching name was found and removed, or if one was not. + public bool Remove(string name) + { + if (_groupLookup.TryGetValue(name, out var v)) + { + _groupLookup.Remove(name); + return true; + } + + return false; + } + + /// + public bool Remove(KeyValuePair item) => Remove(item.Key); + + /// + /// Removes all s. + /// + public void Clear() + { + _groupLookup.Clear(); + } + + /// + /// Returns if a is found with the same name. + /// + /// The name of the global variable group to check for. + /// if a is found with the same name. + public bool ContainsKey(string name) => _groupLookup.ContainsKey(name); + + /// + public bool Contains(KeyValuePair item) => + TryGetValue(item.Key, out var v) && v == item.Value; + + /// + /// Copy all s into the provided array starting at . + /// + /// The array to copy the global variables into. + /// The index to start copying into. + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + foreach (var entry in _groupLookup) + array[arrayIndex++] = new KeyValuePair(entry.Key, entry.Value.Group); + } + + /// + /// Creates a Shallow Copy of this instance. + /// + /// A Shallow Copy of this instance. + public PersistentVariablesSource Clone() + { + var pvs = new PersistentVariablesSource(); + foreach (var entry in _groupLookup) + pvs.Add(entry.Key, entry.Value.Group); + + return pvs; + } + + /// + /// Returns an for all the s in the source. + /// + /// + IEnumerator> IEnumerable>. + GetEnumerator() + { + return _groupLookup.Select(v => new KeyValuePair(v.Key, v.Value.Group)).GetEnumerator(); + } + + /// + /// Returns an for all s in the source. + /// + /// + public IEnumerator GetEnumerator() + { + return _groupLookup.Select(v => new KeyValuePair(v.Key, v.Value.Group)).GetEnumerator(); + } + + /// + public bool TryEvaluateSelector(ISelectorInfo selectorInfo) + { + // First, we test the current value + // If selectorInfo.SelectorOperator== string.Empty, the CurrentValue comes from an arg to the SmartFormatter.Format(...) + // IVariablesGroups from args have priority over PersistentVariablesSource + if (selectorInfo.CurrentValue is IVariablesGroup grp && TryEvaluateGroup(selectorInfo, grp)) + return true; + + if (TryGetValue(selectorInfo.SelectorText, out var group)) + { + selectorInfo.Result = group; + return true; + } + + return false; + } + + private static bool TryEvaluateGroup(ISelectorInfo selectorInfo, IVariablesGroup variablesGroup) + { + if (!variablesGroup.TryGetValue(selectorInfo.SelectorText, out var variable)) return false; + + selectorInfo.Result = variable.GetValue(); + return true; + } + } +} From 0de5f291c569eb8f1410c603a374dc6305e7891c Mon Sep 17 00:00:00 2001 From: axunonb Date: Sun, 19 Dec 2021 01:20:41 +0100 Subject: [PATCH 135/139] SonarCloud hints --- .../Extensions/PersistentVariables/VariableInterfaces.cs | 4 ++-- .../Extensions/PersistentVariables/VariablesGroup.cs | 2 ++ src/SmartFormat/Extensions/PersistentVariablesSource.cs | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs b/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs index 5b2865d4..a7d70e2a 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs @@ -14,10 +14,10 @@ public interface IVariablesGroup /// /// Gets the variable with the matching key if one exists. /// - /// The variable key or name to match. + /// The variable name to match. /// The found variable or null if one could not be found. /// true if a variable could be found or false if one could not. - bool TryGetValue(string key, out IVariable value); + bool TryGetValue(string name, out IVariable value); } /// diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs index e564303c..a892354f 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs @@ -38,7 +38,9 @@ public class VariablesGroup : IVariablesGroup, IVariable, IDictionary /// Gets all the s for this group. /// + #pragma warning disable CA1819 // Properties should not make collection or array copies public ICollection Values => _variableLookup.Values.Select(s => s.Variable).ToList(); + #pragma warning restore CA1819 // Properties should not make collection or array copies /// /// Implemented as part of IDictionary. Always returns . diff --git a/src/SmartFormat/Extensions/PersistentVariablesSource.cs b/src/SmartFormat/Extensions/PersistentVariablesSource.cs index bb976502..04249683 100644 --- a/src/SmartFormat/Extensions/PersistentVariablesSource.cs +++ b/src/SmartFormat/Extensions/PersistentVariablesSource.cs @@ -56,7 +56,9 @@ public NameGroupPair(string name, VariablesGroup group) /// /// Gets the values of stored s. /// + #pragma warning disable CA1819 // Properties should not make collection or array copies public ICollection Values => _groupLookup.Values.Select(k => k.Group).ToList(); + #pragma warning restore CA1819 // Properties should not make collection or array copies /// /// Gets the that matches . From 3a20da0d141045ed510d594baa19d36bbcda1ef1 Mon Sep 17 00:00:00 2001 From: axunonb Date: Sun, 19 Dec 2021 01:44:12 +0100 Subject: [PATCH 136/139] Update #pragmas --- .../Extensions/PersistentVariables/VariablesGroup.cs | 4 +--- src/SmartFormat/Extensions/PersistentVariablesSource.cs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs index a892354f..8cf8efc0 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs @@ -38,9 +38,7 @@ public class VariablesGroup : IVariablesGroup, IVariable, IDictionary /// Gets all the s for this group. /// - #pragma warning disable CA1819 // Properties should not make collection or array copies - public ICollection Values => _variableLookup.Values.Select(s => s.Variable).ToList(); - #pragma warning restore CA1819 // Properties should not make collection or array copies + public ICollection Values => _variableLookup.Values.Select(s => s.Variable).ToList(); //NOSONAR /// /// Implemented as part of IDictionary. Always returns . diff --git a/src/SmartFormat/Extensions/PersistentVariablesSource.cs b/src/SmartFormat/Extensions/PersistentVariablesSource.cs index 04249683..47030e3b 100644 --- a/src/SmartFormat/Extensions/PersistentVariablesSource.cs +++ b/src/SmartFormat/Extensions/PersistentVariablesSource.cs @@ -56,9 +56,7 @@ public NameGroupPair(string name, VariablesGroup group) /// /// Gets the values of stored s. /// - #pragma warning disable CA1819 // Properties should not make collection or array copies - public ICollection Values => _groupLookup.Values.Select(k => k.Group).ToList(); - #pragma warning restore CA1819 // Properties should not make collection or array copies + public ICollection Values => _groupLookup.Values.Select(k => k.Group).ToList(); //NOSONAR /// /// Gets the that matches . From aa2cf9593bc54aa6b85b60f0b456c05fb00d1222 Mon Sep 17 00:00:00 2001 From: axunonb Date: Sun, 19 Dec 2021 17:15:28 +0100 Subject: [PATCH 137/139] Added GlobalVariablesSource --- .../Extensions/GlobalVariableSourceTests.cs | 75 +++++++++++++++++++ .../Extensions/GlobalVariablesSource.cs | 53 +++++++++++++ .../PersistentVariables/VariableInterfaces.cs | 10 +-- .../VariableNameValuePair.cs | 18 +++++ .../PersistentVariables/VariablesGroup.cs | 12 ++- .../Extensions/PersistentVariablesSource.cs | 66 ++++++++++------ 6 files changed, 205 insertions(+), 29 deletions(-) create mode 100644 src/SmartFormat.Tests/Extensions/GlobalVariableSourceTests.cs create mode 100644 src/SmartFormat/Extensions/GlobalVariablesSource.cs diff --git a/src/SmartFormat.Tests/Extensions/GlobalVariableSourceTests.cs b/src/SmartFormat.Tests/Extensions/GlobalVariableSourceTests.cs new file mode 100644 index 00000000..6c6f6944 --- /dev/null +++ b/src/SmartFormat.Tests/Extensions/GlobalVariableSourceTests.cs @@ -0,0 +1,75 @@ +using System.Threading.Tasks; +using NUnit.Framework; +using SmartFormat.Core.Settings; +using SmartFormat.Extensions; +using SmartFormat.Extensions.PersistentVariables; + +namespace SmartFormat.Tests.Extensions +{ + [TestFixture] + public class GlobalVariableSourceTests + { + [Test] + public void Global_Variables_In_Different_SmartFormatters() + { + const string formatString = "{global.theVariable}"; + + var globalGrp = new VariablesGroup + { { "theVariable", new StringVariable("val-from-global-source") } }; + + GlobalVariablesSource.Instance.Add("global", globalGrp); + + var smart1 = new SmartFormatter(); + smart1.FormatterExtensions.Add(new DefaultFormatter()); + smart1.AddExtensions(0, GlobalVariablesSource.Instance); + + var smart2 = new SmartFormatter(); + smart2.FormatterExtensions.Add(new DefaultFormatter()); + smart2.AddExtensions(0, GlobalVariablesSource.Instance); + + var result1 = smart1.Format(formatString); + var result2 = smart2.Format(formatString); + + Assert.That(result1, Is.EqualTo(result2)); + } + + [Test] + public void Reset_Should_Create_A_New_Instance() + { + var globalGrp = new VariablesGroup + { { "theVariable", new StringVariable("val-from-global-source") } }; + + GlobalVariablesSource.Instance.Add("global", globalGrp); + + var ref1 = GlobalVariablesSource.Instance; + GlobalVariablesSource.Reset(); + var ref2 = GlobalVariablesSource.Instance; + + Assert.That(!ReferenceEquals(ref1, ref2), "Different references after ResetInstance()"); + Assert.That(ref2.Count, Is.EqualTo(0)); + } + + [Test] + public void Parallel_Load_By_Adding_Variables_To_Instance() + { + // Switch to thread safety - otherwise the test would throw an InvalidOperationException + const bool currentThreadSafeMode = true; + var savedIsThreadSafeMode = SmartSettings.IsThreadSafeMode; + SmartSettings.IsThreadSafeMode = currentThreadSafeMode; + + GlobalVariablesSource.Instance.Add("global", new VariablesGroup()); + + var options = new ParallelOptions { MaxDegreeOfParallelism = 10 }; + + Assert.That(code: () => + Parallel.For(0L, 1000, options, (i, loopState) => + { + GlobalVariablesSource.Instance["global"].Add($"{i:0000}", new IntVariable((int)i)); + }), Throws.Nothing); + Assert.That(GlobalVariablesSource.Instance["global"].Count, Is.EqualTo(1000)); + + // Restore to saved value + SmartSettings.IsThreadSafeMode = savedIsThreadSafeMode; + } + } +} diff --git a/src/SmartFormat/Extensions/GlobalVariablesSource.cs b/src/SmartFormat/Extensions/GlobalVariablesSource.cs new file mode 100644 index 00000000..918371a2 --- /dev/null +++ b/src/SmartFormat/Extensions/GlobalVariablesSource.cs @@ -0,0 +1,53 @@ +// +// Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. +// Licensed under the MIT license. +// + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Threading; +using SmartFormat.Core.Settings; +using SmartFormat.Extensions.PersistentVariables; + +namespace SmartFormat.Extensions +{ + /// + /// Provides global (static) variables of type to the + /// that do not need to be passed in as arguments when formatting a string. + /// The smart string should take the placeholder format like {groupName.variableName}. + /// Note: s from args to SmartFormatter.Format(...) take precedence over . + /// + public class GlobalVariablesSource : PersistentVariablesSource + { + private readonly IDictionary _globalGroupLookup = SmartSettings.IsThreadSafeMode + ? new ConcurrentDictionary() + : new Dictionary(); + + private static Lazy _lazySource = new(() => new GlobalVariablesSource(), + SmartSettings.IsThreadSafeMode + ? LazyThreadSafetyMode.PublicationOnly + : LazyThreadSafetyMode.None); + + private GlobalVariablesSource() + { + GroupLookup = _globalGroupLookup; + } + + /// + /// Initializes the current with a new, empty instance. + /// + public static void Reset() + { + _lazySource = new Lazy(() => new GlobalVariablesSource(), + SmartSettings.IsThreadSafeMode + ? LazyThreadSafetyMode.PublicationOnly + : LazyThreadSafetyMode.None); + } + + /// + /// Gets the static instance of the . + /// + public static GlobalVariablesSource Instance => _lazySource.Value; + } +} diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs b/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs index a7d70e2a..4c96e881 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs @@ -16,15 +16,15 @@ public interface IVariablesGroup /// /// The variable name to match. /// The found variable or null if one could not be found. - /// true if a variable could be found or false if one could not. + /// if a variable could be found or if one could not. bool TryGetValue(string name, out IVariable value); } /// - /// Represents a variable that can be provided through a global or as a local - /// variable instead of as a SmartFormat argument. - /// A variable can be a single variable, in which case the value should be returned in - /// or a class with multiple variables which can then be further extracted as SmartFormat arguments. + /// Represents a variable that can be provided through a global + /// instead of as a SmartFormat argument. + /// A variable can be a single variable, in which case the value should be returned by + /// or a class with multiple variables () which can then be further extracted as SmartFormat arguments. /// public interface IVariable { diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs b/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs index abd511d9..9289f22c 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs @@ -4,18 +4,36 @@ namespace SmartFormat.Extensions.PersistentVariables { + /// + /// The class for the variable name and its corresponding . + /// internal class NameVariablePair { + /// + /// Creates a new instance. + /// + /// The name of the variable. + /// The . public NameVariablePair(string name, IVariable variable) { Name = name; Variable = variable; } + /// + /// Gets the name of the variable. + /// public string Name { get; } + /// + /// Gets the that corresponds to the variable name. + /// public IVariable Variable { get; } + /// + /// Gets a string with the , and the value from . + /// + /// public override string ToString() => $"'{Name}' - '{Variable.GetValue()?.GetType()}' - '{Variable.GetValue()}'"; } } \ No newline at end of file diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs index 8cf8efc0..2ad6e11e 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs @@ -10,7 +10,7 @@ namespace SmartFormat.Extensions.PersistentVariables /// /// A collection of s that can be used /// as arguments to the Format(...) overloads of , - /// or it can be added to . + /// or it can be added to a or a ///
/// Each instance of keeps its own collection. /// @@ -38,11 +38,17 @@ public class VariablesGroup : IVariablesGroup, IVariable, IDictionary /// Gets all the s for this group. ///
- public ICollection Values => _variableLookup.Values.Select(s => s.Variable).ToList(); //NOSONAR + /// + /// Just implemented as part of . + /// + public ICollection Values => _variableLookup.Values.Select(s => s.Variable).ToList(); //NOSONAR /// - /// Implemented as part of IDictionary. Always returns . + /// Always returns . /// + /// + /// Just implemented as part of . + /// public bool IsReadOnly => false; /// diff --git a/src/SmartFormat/Extensions/PersistentVariablesSource.cs b/src/SmartFormat/Extensions/PersistentVariablesSource.cs index 47030e3b..2c1d7a6d 100644 --- a/src/SmartFormat/Extensions/PersistentVariablesSource.cs +++ b/src/SmartFormat/Extensions/PersistentVariablesSource.cs @@ -14,34 +14,51 @@ namespace SmartFormat.Extensions { /// - /// Provides (global) variables of type to the + /// Provides persistent variables of type to the /// that do not need to be passed in as arguments when formatting a string. /// The smart string should take the placeholder format like {groupName.variableName}. /// Note: s from args to SmartFormatter.Format(...) take precedence over . /// public class PersistentVariablesSource : ISource, IDictionary { - internal class NameGroupPair + /// + /// Contains s and their name. + /// + protected internal class NameGroupPair { + /// + /// CTOR. + /// + /// The name of the . + /// The . public NameGroupPair(string name, VariablesGroup group) { Name = name; Group = group; } + /// + /// Gets the name of the . + /// public string Name { get; } + /// + /// Gets the . + /// public VariablesGroup Group { get; } } - private readonly IDictionary _groupLookup = SmartSettings.IsThreadSafeMode + /// + /// The container for s. + /// + protected IDictionary GroupLookup = SmartSettings.IsThreadSafeMode ? new ConcurrentDictionary() : new Dictionary(); /// /// The number of stored variables. /// - public int Count => _groupLookup.Values.Count; + public int Count => GroupLookup.Values.Count; /// /// Implemented as part of IDictionary. Will always return . @@ -51,21 +68,24 @@ public NameGroupPair(string name, VariablesGroup group) /// /// Gets the names of stored s. /// - public ICollection Keys => _groupLookup.Keys; + public ICollection Keys => GroupLookup.Keys; /// /// Gets the values of stored s. /// - public ICollection Values => _groupLookup.Values.Select(k => k.Group).ToList(); //NOSONAR + /// + /// Just implemented as part of . + /// + public ICollection Values => GroupLookup.Values.Select(k => k.Group).ToList(); //NOSONAR /// - /// Gets the that matches . + /// Gets the that matches the . /// /// The name of the to return. - /// + /// The that matches public VariablesGroup this[string name] { - get => _groupLookup[name].Group; + get => GroupLookup[name].Group; set => Add(name, value); } @@ -77,7 +97,7 @@ public VariablesGroup this[string name] /// if a group could be found or if one could not. public bool TryGetValue(string name, out VariablesGroup value) { - if (_groupLookup.TryGetValue(name, out var v)) + if (GroupLookup.TryGetValue(name, out var v)) { value = v.Group; return true; @@ -100,7 +120,7 @@ public void Add(string name, VariablesGroup group) var pair = new NameGroupPair(name, group); - _groupLookup[name] = pair; + GroupLookup[name] = pair; } /// @@ -113,9 +133,9 @@ public void Add(string name, VariablesGroup group) /// if a with a matching name was found and removed, or if one was not. public bool Remove(string name) { - if (_groupLookup.TryGetValue(name, out var v)) + if (GroupLookup.TryGetValue(name, out var v)) { - _groupLookup.Remove(name); + GroupLookup.Remove(name); return true; } @@ -130,7 +150,7 @@ public bool Remove(string name) /// public void Clear() { - _groupLookup.Clear(); + GroupLookup.Clear(); } /// @@ -138,7 +158,7 @@ public void Clear() /// /// The name of the global variable group to check for. /// if a is found with the same name. - public bool ContainsKey(string name) => _groupLookup.ContainsKey(name); + public bool ContainsKey(string name) => GroupLookup.ContainsKey(name); /// public bool Contains(KeyValuePair item) => @@ -151,18 +171,22 @@ public bool Contains(KeyValuePair item) => /// The index to start copying into. public void CopyTo(KeyValuePair[] array, int arrayIndex) { - foreach (var entry in _groupLookup) + foreach (var entry in GroupLookup) array[arrayIndex++] = new KeyValuePair(entry.Key, entry.Value.Group); } /// - /// Creates a Shallow Copy of this instance. + /// Creates a new instance of , respecting current , + /// with containing variables as a Shallow Copy. /// - /// A Shallow Copy of this instance. + /// + /// A new instance of , respecting current , + /// with containing variables as a Shallow Copy. + /// public PersistentVariablesSource Clone() { var pvs = new PersistentVariablesSource(); - foreach (var entry in _groupLookup) + foreach (var entry in GroupLookup) pvs.Add(entry.Key, entry.Value.Group); return pvs; @@ -175,7 +199,7 @@ public PersistentVariablesSource Clone() IEnumerator> IEnumerable>. GetEnumerator() { - return _groupLookup.Select(v => new KeyValuePair(v.Key, v.Value.Group)).GetEnumerator(); + return GroupLookup.Select(v => new KeyValuePair(v.Key, v.Value.Group)).GetEnumerator(); } /// @@ -184,7 +208,7 @@ IEnumerator> IEnumerable public IEnumerator GetEnumerator() { - return _groupLookup.Select(v => new KeyValuePair(v.Key, v.Value.Group)).GetEnumerator(); + return GroupLookup.Select(v => new KeyValuePair(v.Key, v.Value.Group)).GetEnumerator(); } /// From c03b4c2d5353a9f16c88bfd277a9610a99628aaa Mon Sep 17 00:00:00 2001 From: axunonb Date: Sun, 19 Dec 2021 21:09:53 +0100 Subject: [PATCH 138/139] Added description in CHANGES.md --- CHANGES.md | 97 ++++++++++++++++--- .../PersistentVariableSourceTests.cs | 10 +- .../PersistentVariables.cs | 6 ++ .../PersistentVariables/VariableInterfaces.cs | 6 ++ .../VariableNameValuePair.cs | 6 ++ .../PersistentVariables/VariablesGroup.cs | 10 ++ .../Extensions/PersistentVariablesSource.cs | 6 ++ 7 files changed, 121 insertions(+), 20 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 556639f7..c0552f60 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -111,7 +111,74 @@ In v2, Alignment of output values was limited to the `DefaultFormatter`. It's ab * Introduced `FormatterSettings.AlignmentFillCharacter`, to customize the the fill character. Default is space (0x20), like with `string.Format`. * Modified `ListFormatter` so that items can be aligned (but the spacers stay untouched). -### 8. Added `StringSource` as another `ISource` ([#178](https://github.com/axuno/SmartFormat/pull/178), [#216](https://github.com/axuno/SmartFormat/pull/216)) +### 9. Added `PersistentVariableSource` and `GlobalVariableSource` + +Both provide global variables that are stored in `VariablesGroup` containers to the `SmartFormatter`. These variables are not passed in as arguments when formatting a string. Instead, they are taken from these registered `ISource`s. + +`VariablesGroup`s may contain `Variable`s or other `VariablesGroup`s. The depth of such a tree is unlimited. + +a) `GlobalVariableSource` variables are static and are shared with all `SmartFormatter` instances. +b) `PersistentVariableSource` variables are stored per instance. + +`PersistentVariableSource` and `GlobalVariableSource` must be configured and registered as `ISource` extensions as shown in the example below. + +#### Example + +```Text +PersistentVariablesSource +or GlobalVariablesSource (Containers for Variable / VariablesGroup children) +| ++---- VariablesGroup "group" +| | +| +---- StringVariable "groupString", Value: "groupStringValue" +| | +| +---- Variable "groupDateTime", Value: 2024-12-31 +| ++---- StringVariable "topInteger", Value: 12345 +| ++---- StringVariable "topString", Value: "topStringValue" +``` +Here, we use the `PersistentVariablesSource`: +```CSharp +// The top container +// It gets its name later, when being added to the PersistentVariablesSource +var varGroup = new VariablesGroup(); + +// Add a (nested) VariablesGroup named 'group' to the top container +varGroup.Add("group", new VariablesGroup +{ + // Add variables to the group + { "groupString", new StringVariable("groupStringValue") }, + { "groupDateTime", new Variable(new DateTime(2024, 12, 31)) } +}); +// Add more variables to the container +varGroup.Add("topInteger", new IntVariable(12345)); +varGroup.Add("topString", new StringVariable("topStringValue")); + +// The formatter for persistent variables requires only 2 extensions +var smart = new SmartFormatter(); +smart.FormatterExtensions.Add(new DefaultFormatter()); +var pvs = new PersistentVariablesSource +{ + // Here, the top container gets its name + { "global", varGroup } +}; +// Best to put it to the top of source extensions +smart.AddExtensions(0, pvs); + +// Note: We don't need args to the formatter for PersistentVariablesSource variables +_ = smart.Format(CultureInfo.InvariantCulture, + "{global.group.groupString} {global.group.groupDateTime:'groupDateTime='yyyy-MM-dd}"); +// result: "groupStringValue groupDateTime=2024-12-31" + +_ = smart.Format("{global.topInteger}"); +// result: "12345" + +_ = smart.Format("{global.topString}"); +// result: "topStringValue" +``` + +### 9. Added `StringSource` as another `ISource` ([#178](https://github.com/axuno/SmartFormat/pull/178), [#216](https://github.com/axuno/SmartFormat/pull/216)) The `StringSource` takes over a part of the functionality, which has been implemented in `ReflectionSource` in v2. Compared to reflection **with** caching, speed is 20% better at 25% less memory allocation. `StringSource` brings the following built-in methods (as selector names): @@ -135,7 +202,7 @@ Smart.Format("{0.ToLower.TrimStart.TrimEnd.ToBase64}", " ABCDE "); // result: "YWJjZGU=" ``` -### 9. Introduced Nullable Notation ([#176](https://github.com/axuno/SmartFormat/pull/176)) +### 10. Introduced Nullable Notation ([#176](https://github.com/axuno/SmartFormat/pull/176)) C# like `nullable` notation allows to display `Nullable` types. @@ -149,7 +216,7 @@ All `Format()` methods accept nullable args (**[#196](https://github.com/axuno/S Opposed to `string.Format` null(able) arguments are allowed. -### 10. Added `NullFormatter` ([#176](https://github.com/axuno/SmartFormat/pull/176), [#199](https://github.com/axuno/SmartFormat/pull/199)) +### 11. Added `NullFormatter` ([#176](https://github.com/axuno/SmartFormat/pull/176), [#199](https://github.com/axuno/SmartFormat/pull/199)) In the context of Nullable Notation, the `NullFormatter` has been added. It outputs a custom string literal, if the variable is `null`, else another literal (default is `string.Empty`) or `Placeholder`. @@ -161,7 +228,7 @@ Smart.Format("{TheValue:isnull:The value is null|The value is {}}", new {TheValu // Result: "The value is 1234" ``` -### 11. Added `LocalizationFormatter` ([#176](https://github.com/axuno/SmartFormat/pull/207)) +### 12. Added `LocalizationFormatter` ([#176](https://github.com/axuno/SmartFormat/pull/207)) #### Features * Added `LocalizationFormatter` to localize literals and placeholders @@ -198,14 +265,14 @@ _ = Smart.Format("{0:plural:{:L(fr):{} item}|{:L(fr):{} items}}", 200; // result for French: 200 éléments ``` -### 12. Improved custom `ISource` and `IFormatter` implementations ([#180](https://github.com/axuno/SmartFormat/pull/180)) +### 13. Improved custom `ISource` and `IFormatter` implementations ([#180](https://github.com/axuno/SmartFormat/pull/180)) Any custom exensions can implement `IInitializer`. Then, the `SmartFormatter` will call `Initialize(SmartFormatter smartFormatter)` of the extension, before adding it to the extension list. -### 13. `IFormatter`s have one single, unique name ([#185](https://github.com/axuno/SmartFormat/pull/185)) +### 14. `IFormatter`s have one single, unique name ([#185](https://github.com/axuno/SmartFormat/pull/185)) In v2, `IFormatter`s could have an unlimited number of names. To improve performance, in v3, this is limited to one single, unique name. -### 14. JSON support ([#177](https://github.com/axuno/SmartFormat/pull/177), [#201](https://github.com/axuno/SmartFormat/pull/201)) +### 15. JSON support ([#177](https://github.com/axuno/SmartFormat/pull/177), [#201](https://github.com/axuno/SmartFormat/pull/201)) Separation of `JsonSource` into 2 `ISource` extensions: * `NewtonSoftJsonSource` @@ -213,14 +280,14 @@ Separation of `JsonSource` into 2 `ISource` extensions: Fix: `NewtonSoftJsonSource` handles `null` values correctly ([#201](https://github.com/axuno/SmartFormat/pull/201)) -### 15. `SmartFormatter` takes `IList` parameters +### 16. `SmartFormatter` takes `IList` parameters Added support for `IList` parameters to the `SmartFormatter` (thanks to [@karljj1](https://github.com/karljj1)) ([#154](https://github.com/axuno/SmartFormat/pull/154)) -### 16. `SmartObjects` have been removed +### 18. `SmartObjects` have been removed * Removed obsolete `SmartObjects` (which have been replaced by `ValueTuple`) ([`092b7b1`](https://github.com/axuno/SmartFormat/commit/092b7b1b5873301bdfeb2b62f221f936efc81430)) -### 17. Improved parsing of HTML input ([#203](https://github.com/axuno/SmartFormat/pull/203)) +### 18. Improved parsing of HTML input ([#203](https://github.com/axuno/SmartFormat/pull/203)) Introduced experimental `bool ParserSettings.ParseInputAsHtml`. The default is `false`. @@ -234,7 +301,7 @@ Best results can only be expected with clean HTML: balanced opening and closing SmartFormat is not a fully-fledged HTML parser. If this is required, use [AngleSharp](https://anglesharp.github.io/) or [HtmlAgilityPack](https://html-agility-pack.net/). -### 18. Refactored `PluralLocalizationFormatter` ([#209](https://github.com/axuno/SmartFormat/pull/209)) +### 19. Refactored `PluralLocalizationFormatter` ([#209](https://github.com/axuno/SmartFormat/pull/209)) * Constructor with string argument for default language is obsolete. * Property `DefaultTwoLetterISOLanguageName` is obsolete. @@ -243,7 +310,7 @@ SmartFormat is not a fully-fledged HTML parser. If this is required, use [AngleS b) Get the culture from the `IFormatProvider` argument (which may be a `CultureInfo`) to `SmartFormatter.Format(IFormatProvider, string, object?[])`
c) The `CultureInfo.CurrentUICulture`
-### 19. Refactored `TimeFormatter` ([#220](https://github.com/axuno/SmartFormat/pull/220), [#221](https://github.com/axuno/SmartFormat/pull/221)) +### 20. Refactored `TimeFormatter` ([#220](https://github.com/axuno/SmartFormat/pull/220), [#221](https://github.com/axuno/SmartFormat/pull/221)) * Constructor with string argument for default language is obsolete. * Property `DefaultTwoLetterISOLanguageName` is obsolete. @@ -295,7 +362,7 @@ SmartFormat is not a fully-fledged HTML parser. If this is required, use [AngleS // result: "25 heures 1 minute" ``` -### 20. Thread Safety ([#229](https://github.com/axuno/SmartFormat/pull/229)) +### 21. Thread Safety ([#229](https://github.com/axuno/SmartFormat/pull/229)) SmartFormat makes heavy use of caching and object pooling for expensive operations, which both require `static` containers. @@ -312,7 +379,7 @@ a) Instantiating `SmartFormatter`s from a single thread: The simplified `Smart.Format(...)` API overloads are allowed here. -### 21. How to benefit from object pooling ([#229](https://github.com/axuno/SmartFormat/pull/229)) +### 22. How to benefit from object pooling ([#229](https://github.com/axuno/SmartFormat/pull/229)) In order to return "smart" objects back to the object pool, its important to use one of the following patterns. @@ -340,7 +407,7 @@ var resultString = smart.Format(parsedFormat); parsedFormat.Dispose(); ``` -### 22. Miscellaneous +### 23. Miscellaneous * Since [#228](https://github.com/axuno/SmartFormat/pull/228) there are no more `Cysharp.Text` classes used in the `SmartFormat` namespace * Created class `ZStringBuilder` as a wrapper around `Utf16ValueStringBuilder`. * Replaced occurrences of `Utf16ValueStringBuilder` with `ZStringBuilder`. diff --git a/src/SmartFormat.Tests/Extensions/PersistentVariableSourceTests.cs b/src/SmartFormat.Tests/Extensions/PersistentVariableSourceTests.cs index 3d616440..e743209e 100644 --- a/src/SmartFormat.Tests/Extensions/PersistentVariableSourceTests.cs +++ b/src/SmartFormat.Tests/Extensions/PersistentVariableSourceTests.cs @@ -164,19 +164,19 @@ public void Use_Globals_Without_Args_To_Formatter() { // The top container // It gets its name later, when being added to the PersistentVariablesSource - var varGrp = new VariablesGroup(); + var varGroup = new VariablesGroup(); // Add a (nested) VariablesGroup named 'group' to the top container - varGrp.Add("group", new VariablesGroup + varGroup.Add("group", new VariablesGroup { // Add variables to the nested group { "groupString", new StringVariable("groupStringValue") }, { "groupDateTime", new Variable(new DateTime(2024, 12, 31)) } }); // Add more variables to the top group container - varGrp.Add(new KeyValuePair("topInteger", new IntVariable(12345))); + varGroup.Add(new KeyValuePair("topInteger", new IntVariable(12345))); var stringVar = new StringVariable("topStringValue"); - varGrp.Add("topString", stringVar); + varGroup.Add("topString", stringVar); // The formatter for persistent variables requires only 2 extensions var smart = new SmartFormatter(); @@ -185,7 +185,7 @@ public void Use_Globals_Without_Args_To_Formatter() var pvs = new PersistentVariablesSource { // Here, the top container gets its name - { "global", varGrp } + { "global", varGroup } }; smart.AddExtensions(0, pvs); diff --git a/src/SmartFormat/Extensions/PersistentVariables/PersistentVariables.cs b/src/SmartFormat/Extensions/PersistentVariables/PersistentVariables.cs index c44f287a..c4e22c96 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/PersistentVariables.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/PersistentVariables.cs @@ -2,6 +2,12 @@ // Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. // Licensed under the MIT license. + +/* + Credits to Needle (https://github.com/needle-tools) + and their PersistentVariablesSource extension to Smart.Format + at https://github.com/needle-mirror/com.unity.localization/blob/master/Runtime/Smart%20Format/Extensions/PersistentVariablesSource.cs +*/ namespace SmartFormat.Extensions.PersistentVariables { /// diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs b/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs index 4c96e881..81906673 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariableInterfaces.cs @@ -2,6 +2,12 @@ // Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. // Licensed under the MIT license. + +/* + Credits to Needle (https://github.com/needle-tools) + and their PersistentVariablesSource extension to Smart.Format + at https://github.com/needle-mirror/com.unity.localization/blob/master/Runtime/Smart%20Format/Extensions/PersistentVariablesSource.cs +*/ using System; namespace SmartFormat.Extensions.PersistentVariables diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs b/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs index 9289f22c..3d5c0be7 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariableNameValuePair.cs @@ -2,6 +2,12 @@ // Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. // Licensed under the MIT license. + +/* + Credits to Needle (https://github.com/needle-tools) + and their PersistentVariablesSource extension to Smart.Format + at https://github.com/needle-mirror/com.unity.localization/blob/master/Runtime/Smart%20Format/Extensions/PersistentVariablesSource.cs +*/ namespace SmartFormat.Extensions.PersistentVariables { /// diff --git a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs index 2ad6e11e..50879cde 100644 --- a/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs +++ b/src/SmartFormat/Extensions/PersistentVariables/VariablesGroup.cs @@ -1,3 +1,13 @@ +// +// Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. +// Licensed under the MIT license. + + +/* + Credits to Needle (https://github.com/needle-tools) + and their PersistentVariablesSource extension to Smart.Format + at https://github.com/needle-mirror/com.unity.localization/blob/master/Runtime/Smart%20Format/Extensions/PersistentVariablesSource.cs +*/ using System; using System.Collections; using System.Collections.Concurrent; diff --git a/src/SmartFormat/Extensions/PersistentVariablesSource.cs b/src/SmartFormat/Extensions/PersistentVariablesSource.cs index 2c1d7a6d..8c16f5f1 100644 --- a/src/SmartFormat/Extensions/PersistentVariablesSource.cs +++ b/src/SmartFormat/Extensions/PersistentVariablesSource.cs @@ -2,6 +2,12 @@ // Copyright (C) axuno gGmbH, Scott Rippey, Bernhard Millauer and other contributors. // Licensed under the MIT license. + +/* + Credits to Needle (https://github.com/needle-tools) + and their PersistentVariablesSource extension to Smart.Format + at https://github.com/needle-mirror/com.unity.localization/blob/master/Runtime/Smart%20Format/Extensions/PersistentVariablesSource.cs +*/ using System; using System.Collections; using System.Collections.Concurrent; From b0560f06628c4baa90cc259ddfb526ac586c8636 Mon Sep 17 00:00:00 2001 From: axunonb Date: Sun, 19 Dec 2021 22:00:54 +0100 Subject: [PATCH 139/139] Added reference to PR #233 to CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index c0552f60..3f449798 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -111,7 +111,7 @@ In v2, Alignment of output values was limited to the `DefaultFormatter`. It's ab * Introduced `FormatterSettings.AlignmentFillCharacter`, to customize the the fill character. Default is space (0x20), like with `string.Format`. * Modified `ListFormatter` so that items can be aligned (but the spacers stay untouched). -### 9. Added `PersistentVariableSource` and `GlobalVariableSource` +### 9. Added `PersistentVariableSource` and `GlobalVariableSource` ([#233](https://github.com/axuno/SmartFormat/pull/233)) Both provide global variables that are stored in `VariablesGroup` containers to the `SmartFormatter`. These variables are not passed in as arguments when formatting a string. Instead, they are taken from these registered `ISource`s.

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 literal 0 HcmV?d00001 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Buffers.dll.meta b/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Buffers.dll.meta new file mode 100644 index 00000000..db649ce9 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Buffers.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 8e7af8fe9839770458b3b543b27f9b68 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Memory.dll b/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Memory.dll new file mode 100644 index 0000000000000000000000000000000000000000..bdfc501e9647719549793297acb072d33067d4e5 GIT binary patch literal 148760 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 IXGb{$00BiQzyJUM literal 0 HcmV?d00001 diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Memory.dll.meta b/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Memory.dll.meta new file mode 100644 index 00000000..eae7a542 --- /dev/null +++ b/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Memory.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 093c0580b60756443bc1d9c561452e36 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Runtime.CompilerServices.Unsafe.dll b/src/ZString.Unity/Assets/Scripts/ZString/Samples~/RequiredManagedDLLs/Plugins/System.Runtime.CompilerServices.Unsafe.dll new file mode 100644 index 0000000000000000000000000000000000000000..c66b445c4f964506d6e737a0ce1b898e7cf36841 GIT binary patch literal 16968 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 Date: Sun, 24 Jan 2021 07:17:42 -0300 Subject: [PATCH 105/139] fix package json format --- .../Assets/Scripts/ZString/package.json | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json b/src/ZString.Unity/Assets/Scripts/ZString/package.json index ac6607c6..64e401bd 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/package.json +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json @@ -1,18 +1,21 @@ { - "name": "com.cysharp.zstring", - "displayName": "ZString", - "version": "2.3.1", - "unity": "2018.4", - "description": "Zero Allocation StringBuilder for .NET Core and Unity.", - "keywords": [ "String", "Performance" ], - "license": "MIT", - "category": "Scripting", - "dependencies": {}, + "name": "com.cysharp.zstring", + "displayName": "ZString", + "version": "2.3.1", + "unity": "2018.4", + "description": "Zero Allocation StringBuilder for .NET Core and Unity.", + "keywords": [ + "String", + "Performance" + ], + "license": "MIT", + "category": "Scripting", + "dependencies": {}, "samples": [ { "displayName": "Required Managed DLLs", "description": "Import Required Managed DLLs", "path": "Samples~/RequiredManagedDLLs" - }, + } ] } \ No newline at end of file From b21047179533b7a8ebb3ce6c84b995ea6c11be77 Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Thu, 4 Feb 2021 03:23:47 +0900 Subject: [PATCH 106/139] chore: pr branch is master --- .github/workflows/build-debug.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index c453a8e2..3e1333f7 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -7,9 +7,8 @@ on: tags: - "!*" # not a tag push pull_request: - types: - - opened - - synchronize + branches: + - "master" jobs: build-dotnet: From d28c32c9169216c53b4a5a8f1942f740fab78a5b Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Thu, 4 Feb 2021 03:23:57 +0900 Subject: [PATCH 107/139] chore: detect forgotten .meta file commit --- .github/workflows/build-debug.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index 3e1333f7..6397206e 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -12,6 +12,7 @@ on: jobs: build-dotnet: + if: "!(contains(github.event.head_commit.message, '[skip ci]') || contains(github.event.head_commit.message, '[ci skip]'))" runs-on: ubuntu-latest env: DOTNET_CLI_TELEMETRY_OPTOUT: 1 @@ -26,6 +27,7 @@ jobs: - run: dotnet test tests/ZString.Tests -c Debug < /dev/null build-unity: + if: "!(contains(github.event.head_commit.message, '[skip ci]') || contains(github.event.head_commit.message, '[ci skip]')) && ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:'))" strategy: matrix: unity: ["2019.3.9f1", "2020.1.0b5"] @@ -35,12 +37,17 @@ jobs: - unity: 2020.1.0b5 license: UNITY_2020_1 runs-on: ubuntu-latest + timeout-minutes: 15 container: # with linux-il2cpp. image from https://hub.docker.com/r/gableroux/unity3d/tags image: gableroux/unity3d:${{ matrix.unity }}-linux-il2cpp steps: - - run: apt update && apt install git -y + # Ubuntu 18.04 git is too old, use ppa latest git. + - run: | + apt-get update && apt-get install --no-install-recommends -y software-properties-common && add-apt-repository -y ppa:git-core/ppa + apt-get update && apt-get install --no-install-recommends -y git - uses: actions/checkout@v2 + # activate Unity from manual license file(ulf) - run: echo -n "$UNITY_LICENSE" >> .Unity.ulf env: UNITY_LICENSE: ${{ secrets[matrix.license] }} @@ -52,6 +59,16 @@ jobs: run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export working-directory: src/ZString.Unity + - name: check all .meta is commited + run: | + if git ls-files --others --exclude-standard -t | grep --regexp='[.]meta$'; then + echo "Detected .meta file generated. Do you forgot commit a .meta file?" + exit 1 + else + echo "Great, all .meta files are commited." + fi + working-directory: src/ZString.Unity + # Store artifacts. - uses: actions/upload-artifact@v2 with: From 4e885de18b044ef0d7c311716e16ee88ef81c57d Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Thu, 4 Feb 2021 03:28:35 +0900 Subject: [PATCH 108/139] chore: chore: release on workflow_dispatch --- .github/workflows/build-release.yml | 127 +++++++++++++++++++++++----- 1 file changed, 106 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 0d7d58e7..f795b32c 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -1,35 +1,95 @@ name: Build-Release on: - push: - tags: - - "[0-9]+.[0-9]+.[0-9]+*" + workflow_dispatch: + inputs: + tag: + description: "tag: git tag you want create. (sample 1.0.0)" + required: true + dry_run: + description: "dry_run: true will never create relase/nuget." + required: true + default: "false" + +env: + GIT_TAG: ${{ github.event.inputs.tag }} + DRY_RUN: ${{ github.event.inputs.dry_run }} + DRY_RUN_BRANCH_PREFIX: "test_release" + DOTNET_SDK_VERISON_3: 3.1.x jobs: + update-packagejson: + runs-on: ubuntu-latest + env: + TARGET_FILE: ./src/ZString.Unity/Assets/Scripts/ZString/package.json + outputs: + sha: ${{ steps.commit.outputs.sha }} + steps: + - uses: actions/checkout@v2 + - name: before + run: cat ${{ env.TARGET_FILE}} + - name: update package.json to version ${{ env.GIT_TAG }} + run: sed -i -e "s/\(\"version\":\) \"\(.*\)\",/\1 \"${{ env.GIT_TAG }}\",/" ${{ env.TARGET_FILE }} + - name: after + run: cat ${{ env.TARGET_FILE}} + - name: Commit files + id: commit + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git commit -m "feat: Update package.json to ${{ env.GIT_TAG }}" -a + echo "::set-output name=sha::$(git rev-parse HEAD)" + - name: check sha + run: echo "SHA ${SHA}" + env: + SHA: ${{ steps.commit.outputs.sha }} + - name: tag + run: git tag ${{ env.GIT_TAG }} + if: env.DRY_RUN == 'false' + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} + tags: true + if: env.DRY_RUN == 'false' + - name: Push changes (dry_run) + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ env.DRY_RUN_BRANCH_PREFIX }}-${{ env.GIT_TAG }} + tags: false + if: env.DRY_RUN == 'true' + build-dotnet: + needs: [update-packagejson] runs-on: ubuntu-latest + timeout-minutes: 10 env: DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 NUGET_XMLDOC_MODE: skip steps: + - run: echo ${{ needs.update-packagejson.outputs.sha }} - uses: actions/checkout@v2 + with: + ref: ${{ needs.update-packagejson.outputs.sha }} - uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.x + dotnet-version: "${{ env.DOTNET_SDK_VERSION_3 }}" # set release tag(*.*.*) to env.GIT_TAG - run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - run: dotnet build src/ZString -c Release -p:Version=${{ env.GIT_TAG }} - run: dotnet test tests/ZString.Tests -c Release --no-build - - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} - + - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} -o ./publish # Store artifacts. - uses: actions/upload-artifact@v1 with: name: nuget - path: ./src/ZString/bin/Release/ZString.${{ env.GIT_TAG }}.nupkg + path: ./publish/ build-unity: + needs: [update-packagejson] strategy: matrix: unity: ["2019.3.9f1"] @@ -37,12 +97,19 @@ jobs: - unity: 2019.3.9f1 license: UNITY_2019_3 runs-on: ubuntu-latest + timeout-minutes: 15 container: # with linux-il2cpp. image from https://hub.docker.com/r/gableroux/unity3d/tags image: gableroux/unity3d:${{ matrix.unity }}-linux-il2cpp steps: - - run: apt update && apt install git -y + # Ubuntu 18.04 git is too old, use ppa latest git. + - run: | + apt-get update && apt-get install --no-install-recommends -y software-properties-common && add-apt-repository -y ppa:git-core/ppa + apt-get update && apt-get install --no-install-recommends -y git - uses: actions/checkout@v2 + with: + ref: ${{ needs.update-packagejson.outputs.sha }} + # activate Unity from manual license file(ulf) - run: echo -n "$UNITY_LICENSE" >> .Unity.ulf env: UNITY_LICENSE: ${{ secrets[matrix.license] }} @@ -58,6 +125,16 @@ jobs: env: UNITY_PACKAGE_VERSION: ${{ env.GIT_TAG }} + - name: check all .meta is commited + run: | + if git ls-files --others --exclude-standard -t | grep --regexp='[.]meta$'; then + echo "Detected .meta file generated. Do you forgot commit a .meta file?" + exit 1 + else + echo "Great, all .meta files are commited." + fi + working-directory: src/ZString.Unity + # Store artifacts. - uses: actions/upload-artifact@v1 with: @@ -65,35 +142,32 @@ jobs: path: ./src/ZString.Unity/ZString.Unity.${{ env.GIT_TAG }}.unitypackage create-release: - needs: [build-dotnet, build-unity] + if: github.event.inputs.dry_run == 'false' + needs: [update-packagejson, build-dotnet, build-unity] runs-on: ubuntu-latest env: DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 NUGET_XMLDOC_MODE: skip steps: - # setup dotnet for nuget push - uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.x - # set release tag(*.*.*) to env.GIT_TAG - - run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - - # Create Releases + dotnet-version: "${{ env.DOTNET_SDK_VERSION_3 }}" + # Create Release - uses: actions/create-release@v1 id: create_release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: ${{ github.ref }} - release_name: Ver.${{ github.ref }} - + tag_name: ${{ env.GIT_TAG }} + release_name: Ver.${{ env.GIT_TAG }} + commitish: ${{ needs.update-packagejson.outputs.sha }} + draft: true + prerelease: false # Download (All) Artifacts to current directory - uses: actions/download-artifact@v2-preview - # Upload to NuGet - - run: dotnet nuget push "./nuget/*.nupkg" -s https://www.nuget.org/api/v2/package -k ${{ secrets.NUGET_KEY }} - + - run: dotnet nuget push "./nuget/*.nupkg" --skip-duplicate -s https://www.nuget.org/api/v2/package -k ${{ secrets.NUGET_KEY }} # Upload to Releases(unitypackage) - uses: actions/upload-release-asset@v1 env: @@ -103,3 +177,14 @@ jobs: asset_path: ./ZString.Unity.${{ env.GIT_TAG }}.unitypackage/ZString.Unity.${{ env.GIT_TAG }}.unitypackage asset_name: ZString.Unity.${{ env.GIT_TAG }}.unitypackage asset_content_type: application/octet-stream + + cleanup: + if: github.event.inputs.dry_run == 'true' + needs: [build-dotnet, build-unity] + runs-on: ubuntu-latest + steps: + - name: Delete branch + uses: dawidd6/action-delete-branch@v3 + with: + github_token: ${{ github.token }} + branches: ${{ env.DRY_RUN_BRANCH_PREFIX }}-${{ env.GIT_TAG }} From c55f4c871b9351ea6c4f9519ef2ddcfe95c04d8b Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Mon, 8 Feb 2021 17:53:59 +0900 Subject: [PATCH 109/139] chore: new unity build with unityci/editor --- .github/workflows/build-debug.yml | 36 +++++++++++++---------------- .github/workflows/build-release.yml | 29 ++++++++--------------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml index 6397206e..971eb82d 100644 --- a/.github/workflows/build-debug.yml +++ b/.github/workflows/build-debug.yml @@ -30,34 +30,30 @@ jobs: if: "!(contains(github.event.head_commit.message, '[skip ci]') || contains(github.event.head_commit.message, '[ci skip]')) && ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:'))" strategy: matrix: - unity: ["2019.3.9f1", "2020.1.0b5"] + unity: ["2019.3.9f1", "2019.4.13f1", "2020.1.12f1"] include: - unity: 2019.3.9f1 - license: UNITY_2019_3 - - unity: 2020.1.0b5 - license: UNITY_2020_1 + license: UNITY_LICENSE_2019 + - unity: 2019.4.13f1 + license: UNITY_LICENSE_2019 + - unity: 2020.1.12f1 + license: UNITY_LICENSE_2020 runs-on: ubuntu-latest timeout-minutes: 15 - container: - # with linux-il2cpp. image from https://hub.docker.com/r/gableroux/unity3d/tags - image: gableroux/unity3d:${{ matrix.unity }}-linux-il2cpp steps: - # Ubuntu 18.04 git is too old, use ppa latest git. - - run: | - apt-get update && apt-get install --no-install-recommends -y software-properties-common && add-apt-repository -y ppa:git-core/ppa - apt-get update && apt-get install --no-install-recommends -y git - uses: actions/checkout@v2 - # activate Unity from manual license file(ulf) - - run: echo -n "$UNITY_LICENSE" >> .Unity.ulf - env: - UNITY_LICENSE: ${{ secrets[matrix.license] }} - - name: Activate Unity, always returns a success. But if a subsequent run fails, the activation may have failed(if succeeded, shows `Next license update check is after` and not shows other message(like GUID != GUID). If fails not). In that case, upload the artifact's .alf file to https://license.unity3d.com/manual to get the .ulf file and set it to secrets. - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .Unity.ulf || exit 0 - # Execute scripts: Export Package + # /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export - name: Export unitypackage - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export - working-directory: src/ZString.Unity + uses: game-ci/unity-builder@v2.0-alpha-6 + env: + UNITY_LICENSE: ${{ secrets[matrix.license] }} + with: + projectPath: src/ZString.Unity + unityVersion: ${{ matrix.unity }} + targetPlatform: StandaloneLinux64 + buildMethod: PackageExporter.Export + versioning: None - name: check all .meta is commited run: | diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index f795b32c..a030b991 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -95,35 +95,26 @@ jobs: unity: ["2019.3.9f1"] include: - unity: 2019.3.9f1 - license: UNITY_2019_3 + license: UNITY_LICENSE_2019 runs-on: ubuntu-latest timeout-minutes: 15 - container: - # with linux-il2cpp. image from https://hub.docker.com/r/gableroux/unity3d/tags - image: gableroux/unity3d:${{ matrix.unity }}-linux-il2cpp steps: - # Ubuntu 18.04 git is too old, use ppa latest git. - - run: | - apt-get update && apt-get install --no-install-recommends -y software-properties-common && add-apt-repository -y ppa:git-core/ppa - apt-get update && apt-get install --no-install-recommends -y git - uses: actions/checkout@v2 with: ref: ${{ needs.update-packagejson.outputs.sha }} - # activate Unity from manual license file(ulf) - - run: echo -n "$UNITY_LICENSE" >> .Unity.ulf - env: - UNITY_LICENSE: ${{ secrets[matrix.license] }} - - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .Unity.ulf || exit 0 - - # set release tag(*.*.*) to env.GIT_TAG - - run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - # Execute scripts: Export Package + # /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export - name: Export unitypackage - run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export - working-directory: src/ZString.Unity + uses: game-ci/unity-builder@v2.0-alpha-6 env: + UNITY_LICENSE: ${{ secrets[matrix.license] }} UNITY_PACKAGE_VERSION: ${{ env.GIT_TAG }} + with: + projectPath: src/ZString.Unity + unityVersion: ${{ matrix.unity }} + targetPlatform: StandaloneLinux64 + buildMethod: PackageExporter.Export + versioning: None - name: check all .meta is commited run: | From 8065bf8210cd5b1851a9c392a1ad9711afb3fbe5 Mon Sep 17 00:00:00 2001 From: udaken Date: Sat, 27 Feb 2021 00:47:56 +0900 Subject: [PATCH 110/139] Mantained TextMeshProExtensions.cs --- src/ZString/Unity/TextMeshProExtensions.cs | 12 +++++++++++- src/ZString/Unity/TextMeshProExtensions.tt | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/ZString/Unity/TextMeshProExtensions.cs b/src/ZString/Unity/TextMeshProExtensions.cs index 93c8f6e6..fffb4e48 100644 --- a/src/ZString/Unity/TextMeshProExtensions.cs +++ b/src/ZString/Unity/TextMeshProExtensions.cs @@ -5,6 +5,16 @@ namespace Cysharp.Text { public static partial class TextMeshProExtensions { + public static void SetText(this TMP_Text text, T arg0) + { + using ( var sb = new Cysharp.Text.Utf16ValueStringBuilder( true ) ) + { + sb.Append(arg0); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + public static void SetTextFormat(this TMP_Text text, string format, T0 arg0) { using (var sb = new Cysharp.Text.Utf16ValueStringBuilder(true)) @@ -182,4 +192,4 @@ public static void SetTextFormat(this TMP_Text text, T arg0) + { + using ( var sb = new Cysharp.Text.Utf16ValueStringBuilder( true ) ) + { + sb.Append(arg0); + var array = sb.AsArraySegment(); + text.SetCharArray(array.Array, array.Offset, array.Count); + } + } + <# for(var i = 1; i <= 16; i++) { #> public static void SetTextFormat<<#= CreateTypeArgument(i) #>>(this TMP_Text text, string format, <#= CreateParameters(i) #>) { From 926eba962edf9a9af13679f7be867fcace241aec Mon Sep 17 00:00:00 2001 From: udaken Date: Sun, 28 Feb 2021 14:38:49 +0900 Subject: [PATCH 111/139] Make StringBuilder follow the protocol of IDisposable. --- .../ZString/Utf16ValueStringBuilder.cs | 16 ++++++------ .../Scripts/ZString/Utf8ValueStringBuilder.cs | 16 ++++++------ src/ZString/Utf16ValueStringBuilder.cs | 16 ++++++------ src/ZString/Utf8ValueStringBuilder.cs | 16 ++++++------ tests/ZString.Tests/StringBuilderTest.cs | 26 +++++++++++++++++++ 5 files changed, 58 insertions(+), 32 deletions(-) create mode 100644 tests/ZString.Tests/StringBuilderTest.cs diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index 827192f5..e141402a 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -97,18 +97,18 @@ public Utf16ValueStringBuilder(bool disposeImmediately) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { - if (buffer.Length != ThreadStaticBufferSize) + if (buffer != null) { - if (buffer != null) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } - } - buffer = null; - index = 0; - if (disposeImmediately) - { - scratchBufferUsed = false; + buffer = null; + index = 0; + if (disposeImmediately) + { + scratchBufferUsed = false; + } } } diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs index c30b2b2b..d47df720 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf8ValueStringBuilder.cs @@ -103,18 +103,18 @@ public Utf8ValueStringBuilder(bool disposeImmediately) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { - if (buffer.Length != ThreadStaticBufferSize) + if (buffer != null) { - if (buffer != null) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } - } - buffer = null; - index = 0; - if (disposeImmediately) - { - scratchBufferUsed = false; + buffer = null; + index = 0; + if (disposeImmediately) + { + scratchBufferUsed = false; + } } } diff --git a/src/ZString/Utf16ValueStringBuilder.cs b/src/ZString/Utf16ValueStringBuilder.cs index 827192f5..e141402a 100644 --- a/src/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString/Utf16ValueStringBuilder.cs @@ -97,18 +97,18 @@ public Utf16ValueStringBuilder(bool disposeImmediately) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { - if (buffer.Length != ThreadStaticBufferSize) + if (buffer != null) { - if (buffer != null) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } - } - buffer = null; - index = 0; - if (disposeImmediately) - { - scratchBufferUsed = false; + buffer = null; + index = 0; + if (disposeImmediately) + { + scratchBufferUsed = false; + } } } diff --git a/src/ZString/Utf8ValueStringBuilder.cs b/src/ZString/Utf8ValueStringBuilder.cs index c30b2b2b..d47df720 100644 --- a/src/ZString/Utf8ValueStringBuilder.cs +++ b/src/ZString/Utf8ValueStringBuilder.cs @@ -103,18 +103,18 @@ public Utf8ValueStringBuilder(bool disposeImmediately) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { - if (buffer.Length != ThreadStaticBufferSize) + if (buffer != null) { - if (buffer != null) + if (buffer.Length != ThreadStaticBufferSize) { ArrayPool.Shared.Return(buffer); } - } - buffer = null; - index = 0; - if (disposeImmediately) - { - scratchBufferUsed = false; + buffer = null; + index = 0; + if (disposeImmediately) + { + scratchBufferUsed = false; + } } } diff --git a/tests/ZString.Tests/StringBuilderTest.cs b/tests/ZString.Tests/StringBuilderTest.cs new file mode 100644 index 00000000..79c72742 --- /dev/null +++ b/tests/ZString.Tests/StringBuilderTest.cs @@ -0,0 +1,26 @@ +using Cysharp.Text; +using FluentAssertions; +using System.Text; +using Xunit; + +namespace ZStringTests +{ + public class StringBuilderTest + { + [Fact] + public void Utf16DisposeTest() + { + var sb = ZString.CreateStringBuilder(); + sb.Dispose(); + sb.Dispose(); // call more than once + } + + [Fact] + public void Utf8DisposeTest() + { + var sb = ZString.CreateUtf8StringBuilder(); + sb.Dispose(); + sb.Dispose(); // call more than once + } + } +} From 56b7a7b9876ab5ccecaa03c99051af17f05755a2 Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Mon, 5 Apr 2021 11:08:50 +0900 Subject: [PATCH 112/139] fix: release tag update when package.json has change --- .github/workflows/build-release.yml | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index a030b991..342dc513 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -26,40 +26,51 @@ jobs: sha: ${{ steps.commit.outputs.sha }} steps: - uses: actions/checkout@v2 - - name: before + - name: Output package.json (Before) run: cat ${{ env.TARGET_FILE}} - - name: update package.json to version ${{ env.GIT_TAG }} + + - name: Update package.json to version ${{ env.GIT_TAG }} run: sed -i -e "s/\(\"version\":\) \"\(.*\)\",/\1 \"${{ env.GIT_TAG }}\",/" ${{ env.TARGET_FILE }} - - name: after - run: cat ${{ env.TARGET_FILE}} + + - name: Check update + id: check_update + run: | + cat ${{ env.TARGET_FILE}} + git diff --exit-code || echo "::set-output name=changed::1" + - name: Commit files id: commit + if: steps.check_update.outputs.changed == '1' run: | git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" git commit -m "feat: Update package.json to ${{ env.GIT_TAG }}" -a echo "::set-output name=sha::$(git rev-parse HEAD)" - - name: check sha + + - name: Check sha run: echo "SHA ${SHA}" env: SHA: ${{ steps.commit.outputs.sha }} - - name: tag + + - name: Create Tag + if: steps.check_update.outputs.changed == '1' run: git tag ${{ env.GIT_TAG }} - if: env.DRY_RUN == 'false' + - name: Push changes + if: env.DRY_RUN == 'false' && steps.check_update.outputs.changed == '1' uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} branch: ${{ github.ref }} tags: true - if: env.DRY_RUN == 'false' + - name: Push changes (dry_run) + if: env.DRY_RUN == 'true' && steps.check_update.outputs.changed == '1' uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} branch: ${{ env.DRY_RUN_BRANCH_PREFIX }}-${{ env.GIT_TAG }} tags: false - if: env.DRY_RUN == 'true' build-dotnet: needs: [update-packagejson] From 917a6f9366ae4cd6f42d0ac61ca01f676cea59f7 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 6 Apr 2021 17:25:34 +0900 Subject: [PATCH 113/139] strong named --- ZString.sln | 12 -- opensource.snk | Bin 0 -> 596 bytes sandbox/ConsoleApp/ConsoleApp.csproj | 3 +- sandbox/ConsoleApp/Program.cs | 10 +- .../ConsoleAppNet472/ConsoleAppNet472.csproj | 142 +++++++++--------- src/ZString/ZString.csproj | 2 + src/ZString/_InternalVisibleTo.cs | 8 +- .../ZString.NetCore2Tests.csproj | 2 + tests/ZString.Tests/ZString.Tests.csproj | 44 +++--- 9 files changed, 110 insertions(+), 113 deletions(-) create mode 100644 opensource.snk diff --git a/ZString.sln b/ZString.sln index 4897f7f9..ea3f3561 100644 --- a/ZString.sln +++ b/ZString.sln @@ -23,14 +23,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "sandbox\Conso EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZString.Tests", "tests\ZString.Tests\ZString.Tests.csproj", "{62090C00-9727-4375-BE40-ABE2F4D41571}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppNet472", "sandbox\ConsoleAppNet472\ConsoleAppNet472.csproj", "{BE8A17AA-504A-410D-B86D-92431B0F5594}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZString.NetCore2Tests", "tests\ZString.NetCore2Tests\ZString.NetCore2Tests.csproj", "{62C44156-F55C-4006-B9A2-108DAB340FAC}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PerfBenchmark", "sandbox\PerfBenchmark\PerfBenchmark.csproj", "{D766AEB3-3609-4F1D-8D81-5549F748F372}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BenchmarkVsReleasedVersion", "sandbox\BenchmarkVsReleasedVersion\BenchmarkVsReleasedVersion.csproj", "{94F4D0E1-25FA-4C83-B11A-098754D5554F}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -49,10 +45,6 @@ Global {62090C00-9727-4375-BE40-ABE2F4D41571}.Debug|Any CPU.Build.0 = Debug|Any CPU {62090C00-9727-4375-BE40-ABE2F4D41571}.Release|Any CPU.ActiveCfg = Release|Any CPU {62090C00-9727-4375-BE40-ABE2F4D41571}.Release|Any CPU.Build.0 = Release|Any CPU - {BE8A17AA-504A-410D-B86D-92431B0F5594}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE8A17AA-504A-410D-B86D-92431B0F5594}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE8A17AA-504A-410D-B86D-92431B0F5594}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE8A17AA-504A-410D-B86D-92431B0F5594}.Release|Any CPU.Build.0 = Release|Any CPU {62C44156-F55C-4006-B9A2-108DAB340FAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {62C44156-F55C-4006-B9A2-108DAB340FAC}.Debug|Any CPU.Build.0 = Debug|Any CPU {62C44156-F55C-4006-B9A2-108DAB340FAC}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -61,8 +53,6 @@ Global {D766AEB3-3609-4F1D-8D81-5549F748F372}.Debug|Any CPU.Build.0 = Debug|Any CPU {D766AEB3-3609-4F1D-8D81-5549F748F372}.Release|Any CPU.ActiveCfg = Release|Any CPU {D766AEB3-3609-4F1D-8D81-5549F748F372}.Release|Any CPU.Build.0 = Release|Any CPU - {94F4D0E1-25FA-4C83-B11A-098754D5554F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {94F4D0E1-25FA-4C83-B11A-098754D5554F}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -71,10 +61,8 @@ Global {7B09D422-D19A-457E-ADA0-4CDC2DC581BB} = {B385367D-2EB5-49B3-A3EF-922151EC1904} {9ADF67E1-1872-43D3-882E-607071726FE7} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} {62090C00-9727-4375-BE40-ABE2F4D41571} = {0803618F-C4E8-4D37-831E-5D26C5574F49} - {BE8A17AA-504A-410D-B86D-92431B0F5594} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} {62C44156-F55C-4006-B9A2-108DAB340FAC} = {0803618F-C4E8-4D37-831E-5D26C5574F49} {D766AEB3-3609-4F1D-8D81-5549F748F372} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} - {94F4D0E1-25FA-4C83-B11A-098754D5554F} = {A7D7AA7D-9A79-48A8-978D-0C98EBD81ED0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DF39BF43-3E0E-4F7D-9943-7E50D301234D} diff --git a/opensource.snk b/opensource.snk new file mode 100644 index 0000000000000000000000000000000000000000..8ca75fe9e452fef076bbdf192ec38753db575c54 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa500962MC>T>>F;|N+RR5nT6z^a>I!?RSqDR+ z(Wq}rJ`kv(ClbcyN0w{-i`M8c1dAiRLc7Ip7nOy+6W*Qq)%1s&B7 z-Js;wwq9s-;}0A+&x^~){sPDH=Aff8d<@JMF~4MAKyxJ_`U^p$3>S?E_uY4$LZR+= zCK!|_Vr<`%3pvx}Xao~+Z5c}!&~fC_s}@ImD5!3Y;ErL|wjmReqgfAYc&i^OwrIv@ zV@?CL0S(`MQ=k1uZ`2iUU1bxK+Yd-3-tJ0|gcxsxC&sN2VlB7u1n19DpR9Ivh&p6R zDz985T}&FdF+8Et804qBjW4ed^xg2a?5waJg2^MSf?q436uufK)?t(S2~xE;5$PN; zW$81M0y6WqyDlvM4`m*d5VM;(0g;WHoQx+uROeYS7DDGc>}YEJ!5Y!cAN1(Ix?V0Z zvb{_SG}^x@aiDBj3q=HVAikmLKPcpzQ%rpmgq5NgJFtef&R&+xS*N6WgrMlB9s|jg zI3_8W_=wcGhYP~4O`Pa9v4uIo_KOHv%K_pNU|OO={tzTVb0^9`>F}YJU%!UBa&3D+ z?Rh1QPA$`c&C0n~V6`0_qjA2X4$Nc>4f=+UuCxD~bqrs5-2a86+)(84p=W5x8jh5T zdaYrrhzfZ{$YaHwD#H_44(3EIIpBa$y&YJc8`Oz4ADjQaGsJ91;umWJ-Mxfo9$IOP iH$jT?Lly$oL7)e7%^~QI+$kcTwbCKd6S$&cwI4_h{S*-Z literal 0 HcmV?d00001 diff --git a/sandbox/ConsoleApp/ConsoleApp.csproj b/sandbox/ConsoleApp/ConsoleApp.csproj index 9e6b29f0..c77b5566 100644 --- a/sandbox/ConsoleApp/ConsoleApp.csproj +++ b/sandbox/ConsoleApp/ConsoleApp.csproj @@ -3,10 +3,11 @@ Exe netcoreapp3.1 + true + ../../opensource.snk - diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index b1b0290d..2b06b9ec 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -4,7 +4,7 @@ using System.Collections.Concurrent; using System.Linq; using System.Text; -using System.Text.Formatting; +// using System.Text.Formatting; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -61,9 +61,9 @@ public string ZStringFormat() return ZString.Format(format, x, y); } - public string StringFormatterFormat() - { - return StringBuffer.Format(format, x, y); - } + //public string StringFormatterFormat() + //{ + // return StringBuffer.Format(format, x, y); + //} } } diff --git a/sandbox/ConsoleAppNet472/ConsoleAppNet472.csproj b/sandbox/ConsoleAppNet472/ConsoleAppNet472.csproj index 5e8a2c60..1b93e506 100644 --- a/sandbox/ConsoleAppNet472/ConsoleAppNet472.csproj +++ b/sandbox/ConsoleAppNet472/ConsoleAppNet472.csproj @@ -1,73 +1,75 @@  - - - Debug - AnyCPU - {BE8A17AA-504A-410D-B86D-92431B0F5594} - Exe - ConsoleAppNet472 - ConsoleAppNet472 - v4.7.2 - 512 - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - ..\..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll - - - - ..\..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll - - - - ..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll - - - ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - - - - - - - - - - - - - - - - - - - {7b09d422-d19a-457e-ada0-4cdc2dc581bb} - ZString - - - + + + Debug + AnyCPU + {BE8A17AA-504A-410D-B86D-92431B0F5594} + Exe + ConsoleAppNet472 + ConsoleAppNet472 + v4.7.2 + 512 + true + true + true + ../../opensource.snk + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + ..\..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll + + + + ..\..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll + + + + ..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + + + + + + + + + + + + + + + + + {7b09d422-d19a-457e-ada0-4cdc2dc581bb} + ZString + + + \ No newline at end of file diff --git a/src/ZString/ZString.csproj b/src/ZString/ZString.csproj index e2bfb159..f8118d30 100644 --- a/src/ZString/ZString.csproj +++ b/src/ZString/ZString.csproj @@ -18,6 +18,8 @@ $(PackageProjectUrl) git MIT + true + ../../opensource.snk diff --git a/src/ZString/_InternalVisibleTo.cs b/src/ZString/_InternalVisibleTo.cs index dc6e0b1a..7c47ebd1 100644 --- a/src/ZString/_InternalVisibleTo.cs +++ b/src/ZString/_InternalVisibleTo.cs @@ -1,6 +1,6 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("ConsoleApp")] -[assembly: InternalsVisibleTo("ConsoleAppNet472")] -[assembly: InternalsVisibleTo("ZString.Tests")] -[assembly: InternalsVisibleTo("ZString.NetCore2Tests")] +[assembly: InternalsVisibleTo("ConsoleApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")] +[assembly: InternalsVisibleTo("ConsoleAppNet472, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")] +[assembly: InternalsVisibleTo("ZString.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")] +[assembly: InternalsVisibleTo("ZString.NetCore2Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")] \ No newline at end of file diff --git a/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj b/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj index ec484dbe..2ed06684 100644 --- a/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj +++ b/tests/ZString.NetCore2Tests/ZString.NetCore2Tests.csproj @@ -4,6 +4,8 @@ netcoreapp2.1 false ZStringTests + true + ../../opensource.snk diff --git a/tests/ZString.Tests/ZString.Tests.csproj b/tests/ZString.Tests/ZString.Tests.csproj index e9eec7d5..f84ae43b 100644 --- a/tests/ZString.Tests/ZString.Tests.csproj +++ b/tests/ZString.Tests/ZString.Tests.csproj @@ -1,27 +1,29 @@ - - netcoreapp3.1 - false - ZStringTests - + + netcoreapp3.1 + false + ZStringTests + true + ../../opensource.snk + - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - + + + From fe7f35e9e25b3c2a5c528a95a1c33de4afc4d1d7 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 6 Apr 2021 17:27:58 +0900 Subject: [PATCH 114/139] import --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index b795bccc..20a55e06 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,16 @@ Workround: - Copy Collections from Library/PackageCache to %Project Folder%/Packages - Remove CompilerServices.Unsafe dll from said folder +### Install via git URL + +You can add `https://github.com/Cysharp/ZString.git?path=src/ZString.Unity/Assets/Scripts/ZString` to Package Manager. + +You can install managed DLL from package mangers's samples Import button. + +![image](https://user-images.githubusercontent.com/46207/113681776-56145f00-96fd-11eb-8227-560da9c1a092.png) + +If you want to set a target version, ZString uses the *.*.* release tag so you can specify a version like #2.4.0. For example https://github.com/Cysharp/ZString.git?path=src/ZString.Unity/Assets/Scripts/ZString#2.4.0. + Advanced Tips --- `ZString.CreateStringBuilder(notNested:true)` is a special optimized parameter that uses `ThreadStatic` buffer instead of rent from `ArrayPool`. It is slightly faster but can not use in nested. From fb221915ca5bba293031d1feff00f2be3d463948 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 6 Apr 2021 08:28:15 +0000 Subject: [PATCH 115/139] docs: update TOC --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 20a55e06..150a0c64 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Related project for loggin using with ZString, [Cysharp/ZLogger](https://github. - [Getting Started](#getting-started) - [Reference](#reference) - [Unity](#unity) + - [Install via git URL](#install-via-git-url) - [Advanced Tips](#advanced-tips) - [License](#license) From 0be4d40d1080e33b86beb56ad3ea38d320c72985 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Apr 2021 08:29:14 +0000 Subject: [PATCH 116/139] feat: Update package.json to 2.4.0 --- src/ZString.Unity/Assets/Scripts/ZString/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZString.Unity/Assets/Scripts/ZString/package.json b/src/ZString.Unity/Assets/Scripts/ZString/package.json index 64e401bd..ac5fa73a 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/package.json +++ b/src/ZString.Unity/Assets/Scripts/ZString/package.json @@ -1,7 +1,7 @@ { "name": "com.cysharp.zstring", "displayName": "ZString", - "version": "2.3.1", + "version": "2.4.0", "unity": "2018.4", "description": "Zero Allocation StringBuilder for .NET Core and Unity.", "keywords": [ From 1f7fdcfd579b1c21aff746d3c84c598af6d21298 Mon Sep 17 00:00:00 2001 From: Ikiru Yoshizaki <3856350+guitarrapc@users.noreply.github.com> Date: Tue, 6 Apr 2021 17:55:36 +0900 Subject: [PATCH 117/139] fix: remove non use GIT_TAG --- .github/workflows/build-release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 342dc513..7d5aa957 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -88,8 +88,6 @@ jobs: - uses: actions/setup-dotnet@v1 with: dotnet-version: "${{ env.DOTNET_SDK_VERSION_3 }}" - # set release tag(*.*.*) to env.GIT_TAG - - run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - run: dotnet build src/ZString -c Release -p:Version=${{ env.GIT_TAG }} - run: dotnet test tests/ZString.Tests -c Release --no-build - run: dotnet pack ./src/ZString/ZString.csproj -c Release --no-build -p:Version=${{ env.GIT_TAG }} -o ./publish From 8ac59c0d66bee11d248f5008605dc005655c1895 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Tue, 6 Apr 2021 18:09:12 +0900 Subject: [PATCH 118/139] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 150a0c64..d9329f6a 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ async void Example(int x, int y, int z) // create Utf8 StringBuilder that build Utf8 directly to avoid encoding using var sb2 = ZString.CreateUtf8StringBuilder(); - sb2.Concat("foo:", x, ", bar:", y); + sb2.AppendFormat("foo:{0} bar:{1}", x, y); // directly write to steam or dest to avoid allocation await sb2.WriteToAsync(stream); From 2aec84726d9a4edff514224557c70d9aa016118b Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 13 Apr 2021 13:28:58 +0900 Subject: [PATCH 119/139] improve Utf16StringBuilder.Append performance --- .../Benchmarks/AppendPerformance.cs | 73 +++ .../Benchmarks/StringBuilderAppendJoin.cs | 2 + sandbox/PerfBenchmark/PerfBenchmark.csproj | 25 +- sandbox/PerfBenchmark/Program.cs | 6 +- .../Assets/Scenes/SampleScene.unity | 420 +++++++++++++++++- src/ZString.Unity/Assets/Scenes/Test.cs | 56 ++- .../ZString/Utf16ValueStringBuilder.cs | 13 +- src/ZString/Utf16ValueStringBuilder.cs | 13 +- 8 files changed, 577 insertions(+), 31 deletions(-) create mode 100644 sandbox/PerfBenchmark/Benchmarks/AppendPerformance.cs diff --git a/sandbox/PerfBenchmark/Benchmarks/AppendPerformance.cs b/sandbox/PerfBenchmark/Benchmarks/AppendPerformance.cs new file mode 100644 index 00000000..b9163159 --- /dev/null +++ b/sandbox/PerfBenchmark/Benchmarks/AppendPerformance.cs @@ -0,0 +1,73 @@ +using BenchmarkDotNet.Attributes; +using Cysharp.Text; +using System; +using System.Collections.Generic; +using System.Text; + +namespace PerfBenchmark.Benchmarks +{ + [Config(typeof(BenchmarkConfig))] + public class AppendPerformance + { + List strings; + const int COUNT = 1000; + + public AppendPerformance() + { + strings = new List(); + for (int i = 0; i < 100; i++) + { + strings.Add("123456789"); + } + } + + [Benchmark] + public void ZStringUtf16() + { + for (int i = 0; i < COUNT; i++) + { + using (var sb = ZString.CreateStringBuilder()) + { + for (int j = 0; j < strings.Count; j++) + { + sb.Append(strings[j]); + } + + _ = sb.ToString(); + } + } + } + + //[Benchmark] + //public void ZStringUtf16SpanBased() + //{ + // for (int i = 0; i < COUNT; i++) + // { + // using (var sb = ZString.CreateStringBuilder()) + // { + // for (int j = 0; j < strings.Count; j++) + // { + // sb.AppendSlow(strings[j]); + // } + + // _ = sb.ToString(); + // } + // } + //} + + [Benchmark(Baseline = true)] + public void StringBuilder() + { + for (int i = 0; i < COUNT; i++) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + for (int j = 0; j < strings.Count; j++) + { + sb.Append(strings[j]); + } + + _ = sb.ToString(); + } + } + } +} diff --git a/sandbox/PerfBenchmark/Benchmarks/StringBuilderAppendJoin.cs b/sandbox/PerfBenchmark/Benchmarks/StringBuilderAppendJoin.cs index ce701a68..f9388499 100644 --- a/sandbox/PerfBenchmark/Benchmarks/StringBuilderAppendJoin.cs +++ b/sandbox/PerfBenchmark/Benchmarks/StringBuilderAppendJoin.cs @@ -17,8 +17,10 @@ public StringBuilderAppendJoin() fValues = new[] { 0f, float.MaxValue, float.MinValue }; mValues = new[] { 0m, decimal.MaxValue, decimal.MinValue }; +#if NETCOREAPP || NETSTANDARD2_1 if (StringBuilder() != ZStringBuilder()) throw new Exception(); +#endif } diff --git a/sandbox/PerfBenchmark/PerfBenchmark.csproj b/sandbox/PerfBenchmark/PerfBenchmark.csproj index 03fed0f4..de19a39f 100644 --- a/sandbox/PerfBenchmark/PerfBenchmark.csproj +++ b/sandbox/PerfBenchmark/PerfBenchmark.csproj @@ -1,17 +1,18 @@ - + - - Exe - netcoreapp3.1 - + + Exe + net5.0 + 8.0 + - - - - + + + + - - - + + + diff --git a/sandbox/PerfBenchmark/Program.cs b/sandbox/PerfBenchmark/Program.cs index 1563d617..690575e2 100644 --- a/sandbox/PerfBenchmark/Program.cs +++ b/sandbox/PerfBenchmark/Program.cs @@ -1,6 +1,7 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Environments; using BenchmarkDotNet.Exporters; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Running; @@ -17,7 +18,10 @@ internal class BenchmarkConfig : ManualConfig public BenchmarkConfig() { AddDiagnoser(MemoryDiagnoser.Default); - AddJob(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1)); + AddJob(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1).WithRuntime(CoreRuntime.Core50)); + + // Add Targetframeworks net47 to csproj(removed for CI) + // AddJob(Job.ShortRun.WithWarmupCount(1).WithIterationCount(1).WithRuntime(ClrRuntime.Net47)); } } diff --git a/src/ZString.Unity/Assets/Scenes/SampleScene.unity b/src/ZString.Unity/Assets/Scenes/SampleScene.unity index e5ecd0a0..6d495376 100644 --- a/src/ZString.Unity/Assets/Scenes/SampleScene.unity +++ b/src/ZString.Unity/Assets/Scenes/SampleScene.unity @@ -50,12 +50,11 @@ LightmapSettings: m_BounceScale: 1 m_IndirectOutputScale: 1 m_AlbedoBoost: 1 - m_TemporalCoherenceThreshold: 1 m_EnvironmentLightingMode: 0 m_EnableBakedLightmaps: 0 m_EnableRealtimeLightmaps: 0 m_LightmapEditorSettings: - serializedVersion: 10 + serializedVersion: 12 m_Resolution: 2 m_BakeResolution: 40 m_AtlasSize: 1024 @@ -63,6 +62,7 @@ LightmapSettings: m_AOMaxDistance: 1 m_CompAOExponent: 1 m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 m_Padding: 2 m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 @@ -77,10 +77,16 @@ LightmapSettings: m_PVRDirectSampleCount: 32 m_PVRSampleCount: 500 m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 m_PVRFilterTypeDirect: 0 m_PVRFilterTypeIndirect: 0 m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 + m_PVREnvironmentMIS: 0 m_PVRCulling: 1 m_PVRFilteringGaussRadiusDirect: 1 m_PVRFilteringGaussRadiusIndirect: 5 @@ -88,7 +94,9 @@ LightmapSettings: m_PVRFilteringAtrousPositionSigmaDirect: 0.5 m_PVRFilteringAtrousPositionSigmaIndirect: 2 m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 m_LightingDataAsset: {fileID: 0} m_UseShadowmask: 1 --- !u!196 &4 @@ -116,13 +124,15 @@ NavMeshSettings: --- !u!1 &519420028 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - component: {fileID: 519420032} - component: {fileID: 519420031} - component: {fileID: 519420029} + - component: {fileID: 519420030} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -133,20 +143,41 @@ GameObject: --- !u!81 &519420029 AudioListener: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} m_Enabled: 1 +--- !u!114 &519420030 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: af7cb41eb6ddb6944ae4c758581eb5bc, type: 3} + m_Name: + m_EditorClassIdentifier: + buttonA: {fileID: 1550728148} --- !u!20 &519420031 Camera: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} m_Enabled: 1 serializedVersion: 2 m_ClearFlags: 2 m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -176,8 +207,9 @@ Camera: --- !u!4 &519420032 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: -10} @@ -186,3 +218,365 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &558967754 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 558967755} + - component: {fileID: 558967757} + - component: {fileID: 558967756} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &558967755 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 558967754} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1550728147} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &558967756 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 558967754} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Button +--- !u!222 &558967757 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 558967754} + m_CullTransparentMesh: 0 +--- !u!1 &1160431369 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1160431373} + - component: {fileID: 1160431372} + - component: {fileID: 1160431371} + - component: {fileID: 1160431370} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1160431370 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1160431369} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1160431371 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1160431369} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &1160431372 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1160431369} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1160431373 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1160431369} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 1550728147} + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &1550728146 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1550728147} + - component: {fileID: 1550728150} + - component: {fileID: 1550728149} + - component: {fileID: 1550728148} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1550728147 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1550728146} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 558967755} + m_Father: {fileID: 1160431373} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -95, y: 171} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1550728148 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1550728146} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1550728149} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1550728149 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1550728146} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1550728150 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1550728146} + m_CullTransparentMesh: 0 +--- !u!1 &2082585984 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2082585987} + - component: {fileID: 2082585986} + - component: {fileID: 2082585985} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2082585985 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2082585984} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &2082585986 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2082585984} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &2082585987 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2082585984} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/src/ZString.Unity/Assets/Scenes/Test.cs b/src/ZString.Unity/Assets/Scenes/Test.cs index 5f282702..240923ba 100644 --- a/src/ZString.Unity/Assets/Scenes/Test.cs +++ b/src/ZString.Unity/Assets/Scenes/Test.cs @@ -1 +1,55 @@ - \ No newline at end of file + +using Cysharp.Text; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Profiling; +using UnityEngine.UI; + +public class Test : MonoBehaviour +{ + public Button buttonA; + + private void Start() + { + buttonA.onClick.AddListener(() => + { + int COUNT = 1000; + List strings = new List(); + for (int i = 0; i < 100; i++) + strings.Add("123456789"); + + + Profiler.BeginSample("Append/ZString.StringBuilder()"); + for (int i = 0; i < COUNT; i++) + { + using (var sb = ZString.CreateStringBuilder(true)) + { + for (int j = 0; j < strings.Count; j++) + { + sb.Append(strings[j]); + } + + sb.ToString(); + } + } + Profiler.EndSample(); + + + Profiler.BeginSample("Append/SharedStringBuilderScope()"); + { + for (int i = 0; i < COUNT; i++) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + for (int j = 0; j < strings.Count; j++) + { + sb.Append(strings[j]); + } + + sb.ToString(); + // sb.Clear(); + } + } + Profiler.EndSample(); + }); + } +} \ No newline at end of file diff --git a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs index e141402a..b1d4419e 100644 --- a/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs +++ b/src/ZString.Unity/Assets/Scripts/ZString/Utf16ValueStringBuilder.cs @@ -200,7 +200,16 @@ public void AppendLine(char value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(string value) { +#if UNITY_2018_3_OR_NEWER + if (buffer.Length - index < value.Length) + { + Grow(value.Length); + } + value.CopyTo(0, buffer, index, value.Length); + index += value.Length; +#else Append(value.AsSpan()); +#endif } ///