From 767e3568d3a47c9395c8696f63bd2685783299b9 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 15 Sep 2026 23:08:41 +1000 Subject: [PATCH] Add UTF-8 Parse/TryParse/TryFormat polyfills for BigInteger and Complex Adds the .NET 11 UTF-8 BigInteger Parse/TryParse/TryFormat and Complex TryParse overloads. Complex UTF-8 Parse is skipped because it would collide with BigInteger.Parse as static extension members. Introduces the FeatureNumerics constant, set when System.Numerics is referenced. --- apiCount.include.md | 44 +++--- api_list.include.md | 17 +++ assemblySize.include.md | 80 +++++----- claude.md | 2 +- readme.md | 141 ++++++++++-------- src/ApiBuilderTests/BuildApiTest.cs | 1 + src/ApiBuilderTests/Identifiers.cs | 1 + src/ApiBuilderTests/SplitterTests.cs | 1 + src/Consume/Consume.cs | 22 +++ src/Polyfill/Numbers/BigIntegerPolyfill.cs | 74 +++++++++ src/Polyfill/Numbers/ComplexPolyfill.cs | 30 ++++ src/Polyfill/Polyfill.targets | 32 ++-- .../net10.0/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ src/Split/net10.0/Numbers/ComplexPolyfill.cs | 25 ++++ .../net461/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../net462/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ src/Split/net47/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../net471/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../net472/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ src/Split/net48/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../net481/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../net5.0/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../net6.0/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../net7.0/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ src/Split/net7.0/Numbers/ComplexPolyfill.cs | 25 ++++ .../net8.0/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ src/Split/net8.0/Numbers/ComplexPolyfill.cs | 25 ++++ .../net9.0/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ src/Split/net9.0/Numbers/ComplexPolyfill.cs | 25 ++++ .../Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../Numbers/BigIntegerPolyfill.cs | 60 ++++++++ .../uap10.0/Numbers/BigIntegerPolyfill.cs | 60 ++++++++ src/Tests/Numbers/BigIntegerPolyfillTests.cs | 50 +++++++ src/Tests/Numbers/ComplexPolyfillTests.cs | 24 +++ 39 files changed, 1740 insertions(+), 139 deletions(-) create mode 100644 src/Polyfill/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Polyfill/Numbers/ComplexPolyfill.cs create mode 100644 src/Split/net10.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net10.0/Numbers/ComplexPolyfill.cs create mode 100644 src/Split/net461/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net462/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net47/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net471/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net472/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net48/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net481/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net5.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net6.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net7.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net7.0/Numbers/ComplexPolyfill.cs create mode 100644 src/Split/net8.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net8.0/Numbers/ComplexPolyfill.cs create mode 100644 src/Split/net9.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/net9.0/Numbers/ComplexPolyfill.cs create mode 100644 src/Split/netcoreapp2.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/netcoreapp2.1/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/netcoreapp2.2/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/netcoreapp3.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/netcoreapp3.1/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/netstandard2.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/netstandard2.1/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Split/uap10.0/Numbers/BigIntegerPolyfill.cs create mode 100644 src/Tests/Numbers/BigIntegerPolyfillTests.cs create mode 100644 src/Tests/Numbers/ComplexPolyfillTests.cs diff --git a/apiCount.include.md b/apiCount.include.md index b91c49b8..76746650 100644 --- a/apiCount.include.md +++ b/apiCount.include.md @@ -1,28 +1,28 @@ -**API count: 1172** +**API count: 1180** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 1078 | -| `net462` | 1078 | -| `net47` | 1077 | -| `net471` | 1076 | -| `net472` | 1072 | -| `net48` | 1072 | -| `net481` | 1072 | -| `netstandard2.0` | 1074 | -| `netstandard2.1` | 907 | -| `netcoreapp2.0` | 997 | -| `netcoreapp2.1` | 920 | -| `netcoreapp2.2` | 920 | -| `netcoreapp3.0` | 881 | -| `netcoreapp3.1` | 880 | -| `net5.0` | 758 | -| `net6.0` | 654 | -| `net7.0` | 513 | -| `net8.0` | 392 | -| `net9.0` | 245 | -| `net10.0` | 182 | +| `net461` | 1084 | +| `net462` | 1084 | +| `net47` | 1083 | +| `net471` | 1082 | +| `net472` | 1078 | +| `net48` | 1078 | +| `net481` | 1078 | +| `netstandard2.0` | 1080 | +| `netstandard2.1` | 913 | +| `netcoreapp2.0` | 1003 | +| `netcoreapp2.1` | 926 | +| `netcoreapp2.2` | 926 | +| `netcoreapp3.0` | 887 | +| `netcoreapp3.1` | 886 | +| `net5.0` | 764 | +| `net6.0` | 660 | +| `net7.0` | 521 | +| `net8.0` | 400 | +| `net9.0` | 253 | +| `net10.0` | 190 | | `net11.0` | 58 | -| `uap10.0` | 1064 | +| `uap10.0` | 1070 | diff --git a/api_list.include.md b/api_list.include.md index 30421d64..7d8959d1 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -63,6 +63,16 @@ * `bool TryEncodeToChars(ReadOnlySpan, Span, int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.buffers.text.base64.tryencodetochars?view=net-11.0) +#### BigInteger + + * `BigInteger Parse(ReadOnlySpan, IFormatProvider?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.parse?view=net-11.0#system-numerics-biginteger-parse(system-readonlyspan((system-byte))-system-iformatprovider)) + * `BigInteger Parse(ReadOnlySpan, NumberStyles, IFormatProvider?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.parse?view=net-11.0#system-numerics-biginteger-parse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider)) + * `bool TryFormat(Span, int, ReadOnlySpan, IFormatProvider?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryformat?view=net-11.0#system-numerics-biginteger-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) + * `bool TryParse(ReadOnlySpan, BigInteger)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-numerics-biginteger@)) + * `bool TryParse(ReadOnlySpan, IFormatProvider?, BigInteger)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-iformatprovider-system-numerics-biginteger@)) + * `bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, BigInteger)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider-system-numerics-biginteger@)) + + #### BinaryPrimitives * `double ReadDoubleBigEndian(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.buffers.binary.binaryprimitives.readdoublebigendian?view=net-11.0) @@ -199,6 +209,13 @@ * Note: Derived from invariant casing, so the mapping follows the Unicode version of the running framework rather than the one net11 is built against. +#### Complex + + * `bool TryParse(ReadOnlySpan, IFormatProvider?, Complex)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.complex.tryparse?view=net-11.0#system-numerics-complex-tryparse(system-readonlyspan((system-byte))-system-iformatprovider-system-numerics-complex@)) + * `bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, Complex)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.complex.tryparse?view=net-11.0#system-numerics-complex-tryparse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider-system-numerics-complex@)) + * Note: The matching Parse(ReadOnlySpan, ...) overloads are not polyfilled, since they would collide with BigInteger.Parse(ReadOnlySpan, ...); two static extension members with the same signature cannot coexist on one class. + + #### ConcurrentBag * `void Clear()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentbag-1.clear?view=net-11.0) diff --git a/assemblySize.include.md b/assemblySize.include.md index e84fea85..c056a923 100644 --- a/assemblySize.include.md +++ b/assemblySize.include.md @@ -2,26 +2,26 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 387.0KB | +379.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netstandard2.1 | 8.5KB | 343.0KB | +334.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net461 | 8.5KB | 386.0KB | +377.5KB | +9.0KB | +6.0KB | +9.0KB | +13.5KB | -| net462 | 7.0KB | 389.5KB | +382.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 389.0KB | +382.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net471 | 8.5KB | 388.0KB | +379.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net472 | 8.5KB | 387.0KB | +378.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net48 | 8.5KB | 387.0KB | +378.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net481 | 8.5KB | 387.0KB | +378.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.0 | 9.0KB | 365.0KB | +356.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.1 | 9.0KB | 347.0KB | +338.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp2.2 | 9.0KB | 347.0KB | +338.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp3.0 | 9.5KB | 345.5KB | +336.0KB | +8.5KB | +6.0KB | +9.0KB | +13.5KB | -| netcoreapp3.1 | 9.5KB | 343.5KB | +334.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net5.0 | 9.5KB | 309.0KB | +299.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net6.0 | 10.0KB | 250.0KB | +240.0KB | +10.0KB | +7.0KB | +512bytes | +3.5KB | -| net7.0 | 10.0KB | 218.5KB | +208.5KB | +9.5KB | +6.0KB | +1.0KB | +3.5KB | -| net8.0 | 9.5KB | 189.5KB | +180.0KB | +8.0KB | | +512bytes | +3.0KB | -| net9.0 | 9.5KB | 118.0KB | +108.5KB | +8.5KB | | +512bytes | +3.5KB | -| net10.0 | 10.0KB | 93.5KB | +83.5KB | +8.5KB | | +512bytes | +3.0KB | +| netstandard2.0 | 8.0KB | 388.5KB | +380.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netstandard2.1 | 8.5KB | 344.5KB | +336.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net461 | 8.5KB | 387.0KB | +378.5KB | +9.5KB | +6.5KB | +9.0KB | +14.0KB | +| net462 | 7.0KB | 391.0KB | +384.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| net47 | 7.0KB | 390.5KB | +383.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net471 | 8.5KB | 389.5KB | +381.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net472 | 8.5KB | 388.5KB | +380.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net48 | 8.5KB | 388.5KB | +380.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net481 | 8.5KB | 388.5KB | +380.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.0 | 9.0KB | 366.5KB | +357.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.1 | 9.0KB | 348.5KB | +339.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp2.2 | 9.0KB | 348.5KB | +339.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp3.0 | 9.5KB | 346.5KB | +337.0KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | +| netcoreapp3.1 | 9.5KB | 345.0KB | +335.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net5.0 | 9.5KB | 310.5KB | +301.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net6.0 | 10.0KB | 251.5KB | +241.5KB | +10.0KB | +7.0KB | +512bytes | +3.5KB | +| net7.0 | 10.0KB | 221.0KB | +211.0KB | +9.0KB | +5.5KB | +512bytes | +3.5KB | +| net8.0 | 9.5KB | 191.5KB | +182.0KB | +8.5KB | | +512bytes | +3.0KB | +| net9.0 | 9.5KB | 120.0KB | +110.5KB | +8.5KB | | +512bytes | +3.5KB | +| net10.0 | 10.0KB | 95.5KB | +85.5KB | +8.5KB | | +512bytes | +3.5KB | | net11.0 | 10.0KB | 21.0KB | +11.0KB | +9.0KB | | +512bytes | +3.5KB | @@ -29,24 +29,24 @@ | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 563.3KB | +555.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netstandard2.1 | 8.5KB | 492.3KB | +483.8KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net461 | 8.5KB | 563.3KB | +554.8KB | +16.7KB | +7.7KB | +13.9KB | +18.9KB | -| net462 | 7.0KB | 566.8KB | +559.8KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 566.1KB | +559.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net471 | 8.5KB | 564.7KB | +556.2KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net472 | 8.5KB | 562.6KB | +554.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net48 | 8.5KB | 562.6KB | +554.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net481 | 8.5KB | 562.6KB | +554.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.0 | 9.0KB | 530.7KB | +521.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 500.5KB | +491.5KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp2.2 | 9.0KB | 500.5KB | +491.5KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp3.0 | 9.5KB | 492.3KB | +482.8KB | +16.2KB | +7.7KB | +13.9KB | +18.9KB | -| netcoreapp3.1 | 9.5KB | 490.3KB | +480.8KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net5.0 | 9.5KB | 438.4KB | +428.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net6.0 | 10.0KB | 359.2KB | +349.2KB | +17.7KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 310.9KB | +300.9KB | +17.1KB | +7.4KB | +1.6KB | +4.2KB | -| net8.0 | 9.5KB | 268.1KB | +258.6KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | -| net9.0 | 9.5KB | 170.6KB | +161.1KB | +16.0KB | | +1.1KB | +4.2KB | -| net10.0 | 10.0KB | 136.1KB | +126.1KB | +16.0KB | | +1.1KB | +3.7KB | +| netstandard2.0 | 8.0KB | 565.4KB | +557.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netstandard2.1 | 8.5KB | 494.4KB | +485.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 564.9KB | +556.4KB | +17.2KB | +8.2KB | +13.9KB | +19.4KB | +| net462 | 7.0KB | 568.9KB | +561.9KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| net47 | 7.0KB | 568.2KB | +561.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net471 | 8.5KB | 566.8KB | +558.3KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net472 | 8.5KB | 564.7KB | +556.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net48 | 8.5KB | 564.7KB | +556.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net481 | 8.5KB | 564.7KB | +556.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.0 | 9.0KB | 532.8KB | +523.8KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 502.6KB | +493.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp2.2 | 9.0KB | 502.6KB | +493.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp3.0 | 9.5KB | 494.0KB | +484.5KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | +| netcoreapp3.1 | 9.5KB | 492.4KB | +482.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net5.0 | 9.5KB | 440.5KB | +431.0KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net6.0 | 10.0KB | 361.3KB | +351.3KB | +17.7KB | +8.7KB | +1.1KB | +4.2KB | +| net7.0 | 10.0KB | 314.3KB | +304.3KB | +16.6KB | +6.9KB | +1.1KB | +4.2KB | +| net8.0 | 9.5KB | 271.0KB | +261.5KB | +16.0KB | +299bytes | +1.1KB | +3.7KB | +| net9.0 | 9.5KB | 173.6KB | +164.1KB | +16.0KB | | +1.1KB | +4.2KB | +| net10.0 | 10.0KB | 139.1KB | +129.1KB | +16.0KB | | +1.1KB | +4.2KB | | net11.0 | 10.0KB | 30.9KB | +20.9KB | +16.5KB | | +1.1KB | +4.2KB | diff --git a/claude.md b/claude.md index aaef62e8..85c38298 100644 --- a/claude.md +++ b/claude.md @@ -54,7 +54,7 @@ The NuGet package ships `.cs` files (not a DLL). The `Polyfill.nuspec` packs fil Polyfill uses extensive `#if` directives. Key constants: - **Framework constants**: `NETFRAMEWORK`, `NETSTANDARD`, `NETCOREAPP2X`, `NETCOREAPP3X`, `NET46X`, `NET47X`, `NET48X` -- **Feature constants** (set by `Polyfill.targets` based on referenced packages): `FeatureMemory`, `FeatureValueTask`, `FeatureValueTuple`, `FeatureRuntimeInformation`, `FeatureHttp`, `FeatureCompression`, `FeatureAsyncInterfaces` +- **Feature constants** (set by `Polyfill.targets` based on referenced packages): `FeatureMemory`, `FeatureValueTask`, `FeatureValueTuple`, `FeatureRuntimeInformation`, `FeatureHttp`, `FeatureCompression`, `FeatureNumerics`, `FeatureAsyncInterfaces` - **Consumer options**: `PolyPublic` (makes APIs public), `PolyUseEmbeddedAttribute`, `PolyEnsure`, `PolyGuard`, `PolyNullability`, `PolyArgumentExceptions`, `PolyStringInterpolation` - **`AllowUnsafeBlocks`** — enables unsafe polyfill variants for better performance diff --git a/readme.md b/readme.md index 964eef11..a348bd98 100644 --- a/readme.md +++ b/readme.md @@ -13,34 +13,34 @@ The package targets `netstandard2.0` and is designed to support the following ru * `uap10` -**API count: 1172** +**API count: 1180** ### Per Target Framework | Target | APIs | | -- | -- | -| `net461` | 1078 | -| `net462` | 1078 | -| `net47` | 1077 | -| `net471` | 1076 | -| `net472` | 1072 | -| `net48` | 1072 | -| `net481` | 1072 | -| `netstandard2.0` | 1074 | -| `netstandard2.1` | 907 | -| `netcoreapp2.0` | 997 | -| `netcoreapp2.1` | 920 | -| `netcoreapp2.2` | 920 | -| `netcoreapp3.0` | 881 | -| `netcoreapp3.1` | 880 | -| `net5.0` | 758 | -| `net6.0` | 654 | -| `net7.0` | 513 | -| `net8.0` | 392 | -| `net9.0` | 245 | -| `net10.0` | 182 | +| `net461` | 1084 | +| `net462` | 1084 | +| `net47` | 1083 | +| `net471` | 1082 | +| `net472` | 1078 | +| `net48` | 1078 | +| `net481` | 1078 | +| `netstandard2.0` | 1080 | +| `netstandard2.1` | 913 | +| `netcoreapp2.0` | 1003 | +| `netcoreapp2.1` | 926 | +| `netcoreapp2.2` | 926 | +| `netcoreapp3.0` | 887 | +| `netcoreapp3.1` | 886 | +| `net5.0` | 764 | +| `net6.0` | 660 | +| `net7.0` | 521 | +| `net8.0` | 400 | +| `net9.0` | 253 | +| `net10.0` | 190 | | `net11.0` | 58 | -| `uap10.0` | 1064 | +| `uap10.0` | 1070 | @@ -96,26 +96,26 @@ This project uses features from the newest stable SDK and C# language. As such c | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 387.0KB | +379.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netstandard2.1 | 8.5KB | 343.0KB | +334.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net461 | 8.5KB | 386.0KB | +377.5KB | +9.0KB | +6.0KB | +9.0KB | +13.5KB | -| net462 | 7.0KB | 389.5KB | +382.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | -| net47 | 7.0KB | 389.0KB | +382.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net471 | 8.5KB | 388.0KB | +379.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net472 | 8.5KB | 387.0KB | +378.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net48 | 8.5KB | 387.0KB | +378.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| net481 | 8.5KB | 387.0KB | +378.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.0 | 9.0KB | 365.0KB | +356.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | -| netcoreapp2.1 | 9.0KB | 347.0KB | +338.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp2.2 | 9.0KB | 347.0KB | +338.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| netcoreapp3.0 | 9.5KB | 345.5KB | +336.0KB | +8.5KB | +6.0KB | +9.0KB | +13.5KB | -| netcoreapp3.1 | 9.5KB | 343.5KB | +334.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net5.0 | 9.5KB | 309.0KB | +299.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | -| net6.0 | 10.0KB | 250.0KB | +240.0KB | +10.0KB | +7.0KB | +512bytes | +3.5KB | -| net7.0 | 10.0KB | 218.5KB | +208.5KB | +9.5KB | +6.0KB | +1.0KB | +3.5KB | -| net8.0 | 9.5KB | 189.5KB | +180.0KB | +8.0KB | | +512bytes | +3.0KB | -| net9.0 | 9.5KB | 118.0KB | +108.5KB | +8.5KB | | +512bytes | +3.5KB | -| net10.0 | 10.0KB | 93.5KB | +83.5KB | +8.5KB | | +512bytes | +3.0KB | +| netstandard2.0 | 8.0KB | 388.5KB | +380.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netstandard2.1 | 8.5KB | 344.5KB | +336.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net461 | 8.5KB | 387.0KB | +378.5KB | +9.5KB | +6.5KB | +9.0KB | +14.0KB | +| net462 | 7.0KB | 391.0KB | +384.0KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| net47 | 7.0KB | 390.5KB | +383.5KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net471 | 8.5KB | 389.5KB | +381.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net472 | 8.5KB | 388.5KB | +380.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net48 | 8.5KB | 388.5KB | +380.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| net481 | 8.5KB | 388.5KB | +380.0KB | +9.0KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.0 | 9.0KB | 366.5KB | +357.5KB | +8.5KB | +6.5KB | +9.0KB | +13.5KB | +| netcoreapp2.1 | 9.0KB | 348.5KB | +339.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp2.2 | 9.0KB | 348.5KB | +339.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| netcoreapp3.0 | 9.5KB | 346.5KB | +337.0KB | +9.5KB | +7.0KB | +9.5KB | +14.0KB | +| netcoreapp3.1 | 9.5KB | 345.0KB | +335.5KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net5.0 | 9.5KB | 310.5KB | +301.0KB | +9.0KB | +6.5KB | +9.0KB | +14.0KB | +| net6.0 | 10.0KB | 251.5KB | +241.5KB | +10.0KB | +7.0KB | +512bytes | +3.5KB | +| net7.0 | 10.0KB | 221.0KB | +211.0KB | +9.0KB | +5.5KB | +512bytes | +3.5KB | +| net8.0 | 9.5KB | 191.5KB | +182.0KB | +8.5KB | | +512bytes | +3.0KB | +| net9.0 | 9.5KB | 120.0KB | +110.5KB | +8.5KB | | +512bytes | +3.5KB | +| net10.0 | 10.0KB | 95.5KB | +85.5KB | +8.5KB | | +512bytes | +3.5KB | | net11.0 | 10.0KB | 21.0KB | +11.0KB | +9.0KB | | +512bytes | +3.5KB | @@ -123,26 +123,26 @@ This project uses features from the newest stable SDK and C# language. As such c | | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability | |----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------| -| netstandard2.0 | 8.0KB | 563.3KB | +555.3KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netstandard2.1 | 8.5KB | 492.3KB | +483.8KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net461 | 8.5KB | 563.3KB | +554.8KB | +16.7KB | +7.7KB | +13.9KB | +18.9KB | -| net462 | 7.0KB | 566.8KB | +559.8KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | -| net47 | 7.0KB | 566.1KB | +559.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net471 | 8.5KB | 564.7KB | +556.2KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net472 | 8.5KB | 562.6KB | +554.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net48 | 8.5KB | 562.6KB | +554.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| net481 | 8.5KB | 562.6KB | +554.1KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.0 | 9.0KB | 530.7KB | +521.7KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | -| netcoreapp2.1 | 9.0KB | 500.5KB | +491.5KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp2.2 | 9.0KB | 500.5KB | +491.5KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| netcoreapp3.0 | 9.5KB | 492.3KB | +482.8KB | +16.2KB | +7.7KB | +13.9KB | +18.9KB | -| netcoreapp3.1 | 9.5KB | 490.3KB | +480.8KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net5.0 | 9.5KB | 438.4KB | +428.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | -| net6.0 | 10.0KB | 359.2KB | +349.2KB | +17.7KB | +8.7KB | +1.1KB | +4.2KB | -| net7.0 | 10.0KB | 310.9KB | +300.9KB | +17.1KB | +7.4KB | +1.6KB | +4.2KB | -| net8.0 | 9.5KB | 268.1KB | +258.6KB | +15.5KB | +299bytes | +1.1KB | +3.7KB | -| net9.0 | 9.5KB | 170.6KB | +161.1KB | +16.0KB | | +1.1KB | +4.2KB | -| net10.0 | 10.0KB | 136.1KB | +126.1KB | +16.0KB | | +1.1KB | +3.7KB | +| netstandard2.0 | 8.0KB | 565.4KB | +557.4KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netstandard2.1 | 8.5KB | 494.4KB | +485.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net461 | 8.5KB | 564.9KB | +556.4KB | +17.2KB | +8.2KB | +13.9KB | +19.4KB | +| net462 | 7.0KB | 568.9KB | +561.9KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| net47 | 7.0KB | 568.2KB | +561.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net471 | 8.5KB | 566.8KB | +558.3KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net472 | 8.5KB | 564.7KB | +556.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net48 | 8.5KB | 564.7KB | +556.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| net481 | 8.5KB | 564.7KB | +556.2KB | +16.7KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.0 | 9.0KB | 532.8KB | +523.8KB | +16.2KB | +8.2KB | +13.9KB | +18.9KB | +| netcoreapp2.1 | 9.0KB | 502.6KB | +493.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp2.2 | 9.0KB | 502.6KB | +493.6KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| netcoreapp3.0 | 9.5KB | 494.0KB | +484.5KB | +17.2KB | +8.7KB | +14.4KB | +19.4KB | +| netcoreapp3.1 | 9.5KB | 492.4KB | +482.9KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net5.0 | 9.5KB | 440.5KB | +431.0KB | +16.7KB | +8.2KB | +13.9KB | +19.4KB | +| net6.0 | 10.0KB | 361.3KB | +351.3KB | +17.7KB | +8.7KB | +1.1KB | +4.2KB | +| net7.0 | 10.0KB | 314.3KB | +304.3KB | +16.6KB | +6.9KB | +1.1KB | +4.2KB | +| net8.0 | 9.5KB | 271.0KB | +261.5KB | +16.0KB | +299bytes | +1.1KB | +3.7KB | +| net9.0 | 9.5KB | 173.6KB | +164.1KB | +16.0KB | | +1.1KB | +4.2KB | +| net10.0 | 10.0KB | 139.1KB | +129.1KB | +16.0KB | | +1.1KB | +4.2KB | | net11.0 | 10.0KB | 30.9KB | +20.9KB | +16.5KB | | +1.1KB | +4.2KB | @@ -730,6 +730,16 @@ The class `Polyfill` includes the following extension methods: * `bool TryEncodeToChars(ReadOnlySpan, Span, int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.buffers.text.base64.tryencodetochars?view=net-11.0) +#### BigInteger + + * `BigInteger Parse(ReadOnlySpan, IFormatProvider?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.parse?view=net-11.0#system-numerics-biginteger-parse(system-readonlyspan((system-byte))-system-iformatprovider)) + * `BigInteger Parse(ReadOnlySpan, NumberStyles, IFormatProvider?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.parse?view=net-11.0#system-numerics-biginteger-parse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider)) + * `bool TryFormat(Span, int, ReadOnlySpan, IFormatProvider?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryformat?view=net-11.0#system-numerics-biginteger-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) + * `bool TryParse(ReadOnlySpan, BigInteger)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-numerics-biginteger@)) + * `bool TryParse(ReadOnlySpan, IFormatProvider?, BigInteger)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-iformatprovider-system-numerics-biginteger@)) + * `bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, BigInteger)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider-system-numerics-biginteger@)) + + #### BinaryPrimitives * `double ReadDoubleBigEndian(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.buffers.binary.binaryprimitives.readdoublebigendian?view=net-11.0) @@ -866,6 +876,13 @@ The class `Polyfill` includes the following extension methods: * Note: Derived from invariant casing, so the mapping follows the Unicode version of the running framework rather than the one net11 is built against. +#### Complex + + * `bool TryParse(ReadOnlySpan, IFormatProvider?, Complex)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.complex.tryparse?view=net-11.0#system-numerics-complex-tryparse(system-readonlyspan((system-byte))-system-iformatprovider-system-numerics-complex@)) + * `bool TryParse(ReadOnlySpan, NumberStyles, IFormatProvider?, Complex)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.complex.tryparse?view=net-11.0#system-numerics-complex-tryparse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider-system-numerics-complex@)) + * Note: The matching Parse(ReadOnlySpan, ...) overloads are not polyfilled, since they would collide with BigInteger.Parse(ReadOnlySpan, ...); two static extension members with the same signature cannot coexist on one class. + + #### ConcurrentBag * `void Clear()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentbag-1.clear?view=net-11.0) diff --git a/src/ApiBuilderTests/BuildApiTest.cs b/src/ApiBuilderTests/BuildApiTest.cs index 8f3b67ba..62268d20 100644 --- a/src/ApiBuilderTests/BuildApiTest.cs +++ b/src/ApiBuilderTests/BuildApiTest.cs @@ -84,6 +84,7 @@ static int CountApisForSplitFramework(string framework) "FeatureValueTask", "FeatureValueTuple", "FeatureCompression", + "FeatureNumerics", "FeatureAsyncInterfaces", "FeatureUnsafe" }; diff --git a/src/ApiBuilderTests/Identifiers.cs b/src/ApiBuilderTests/Identifiers.cs index cdee076b..0ce05a34 100644 --- a/src/ApiBuilderTests/Identifiers.cs +++ b/src/ApiBuilderTests/Identifiers.cs @@ -36,6 +36,7 @@ public static IEnumerable ReadTypesForFile(string file) "FeatureValueTask", "FeatureValueTuple", "FeatureCompression", + "FeatureNumerics", "FeatureAsyncInterfaces", "FeatureUnsafe" ]; diff --git a/src/ApiBuilderTests/SplitterTests.cs b/src/ApiBuilderTests/SplitterTests.cs index a50444a7..174268cf 100644 --- a/src/ApiBuilderTests/SplitterTests.cs +++ b/src/ApiBuilderTests/SplitterTests.cs @@ -599,6 +599,7 @@ public async Task FeatureSymbols_NotInKnownSymbols() await Assert.That(Splitter.AllKnownFrameworkSymbols.Contains("FeatureValueTask")).IsFalse(); await Assert.That(Splitter.AllKnownFrameworkSymbols.Contains("FeatureHttp")).IsFalse(); await Assert.That(Splitter.AllKnownFrameworkSymbols.Contains("FeatureCompression")).IsFalse(); + await Assert.That(Splitter.AllKnownFrameworkSymbols.Contains("FeatureNumerics")).IsFalse(); await Assert.That(Splitter.AllKnownFrameworkSymbols.Contains("PolyPublic")).IsFalse(); await Assert.That(Splitter.AllKnownFrameworkSymbols.Contains("PolyEnsure")).IsFalse(); await Assert.That(Splitter.AllKnownFrameworkSymbols.Contains("PolyUseEmbeddedAttribute")).IsFalse(); diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index af3a0759..5557bdfb 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -1055,6 +1055,28 @@ void Decimal_Methods() #endif } +#if FeatureNumerics && FeatureMemory + void BigInteger_Methods() + { + BigInteger.Parse(utf8Text: "1"u8); + BigInteger.Parse(utf8Text: "1"u8, style: NumberStyles.Integer, provider: null); + BigInteger.Parse(utf8Text: "1"u8, provider: null); + BigInteger.TryParse(utf8Text: "1"u8, result: out _); + BigInteger.TryParse(utf8Text: "1"u8, style: NumberStyles.Integer, provider: null, result: out _); + BigInteger.TryParse(utf8Text: "1"u8, provider: null, result: out _); + BigInteger.One.TryFormat(utf8Destination: new byte[10], bytesWritten: out _); + BigInteger.One.TryFormat(utf8Destination: new byte[10], bytesWritten: out _, format: "N0", provider: null); + } +#endif + +#if FeatureNumerics && NET7_0_OR_GREATER + void Complex_Methods() + { + Complex.TryParse(utf8Text: "1"u8, style: NumberStyles.Float, provider: null, result: out _); + Complex.TryParse(utf8Text: "1"u8, provider: null, result: out _); + } +#endif + void Double_Methods() { double.TryParse(s: "1", provider: null, result: out _); diff --git a/src/Polyfill/Numbers/BigIntegerPolyfill.cs b/src/Polyfill/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..c93a2606 --- /dev/null +++ b/src/Polyfill/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,74 @@ +#if FeatureNumerics && FeatureMemory && !NET11_0_OR_GREATER + +namespace Polyfills; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +// ReSharper disable once RedundantUsingDirective +using System.Text; + +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.parse?view=net-11.0#system-numerics-biginteger-parse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider) + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + + /// + /// Parses a span of UTF-8 characters into a value. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.parse?view=net-11.0#system-numerics-biginteger-parse(system-readonlyspan((system-byte))-system-iformatprovider) + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-numerics-biginteger@) + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider-system-numerics-biginteger@) + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryparse?view=net-11.0#system-numerics-biginteger-tryparse(system-readonlyspan((system-byte))-system-iformatprovider-system-numerics-biginteger@) + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.tryformat?view=net-11.0#system-numerics-biginteger-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider) + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Polyfill/Numbers/ComplexPolyfill.cs b/src/Polyfill/Numbers/ComplexPolyfill.cs new file mode 100644 index 00000000..10770528 --- /dev/null +++ b/src/Polyfill/Numbers/ComplexPolyfill.cs @@ -0,0 +1,30 @@ +#if FeatureNumerics && NET7_0_OR_GREATER && !NET11_0_OR_GREATER + +namespace Polyfills; + +using System; +using System.Globalization; +using System.Numerics; +using System.Text; + +static partial class Polyfill +{ + extension(Complex) + { + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.complex.tryparse?view=net-11.0#system-numerics-complex-tryparse(system-readonlyspan((system-byte))-system-globalization-numberstyles-system-iformatprovider-system-numerics-complex@) + //Note: The matching Parse(ReadOnlySpan, ...) overloads are not polyfilled, since they would collide with BigInteger.Parse(ReadOnlySpan, ...); two static extension members with the same signature cannot coexist on one class. + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + //Link: https://learn.microsoft.com/en-us/dotnet/api/system.numerics.complex.tryparse?view=net-11.0#system-numerics-complex-tryparse(system-readonlyspan((system-byte))-system-iformatprovider-system-numerics-complex@) + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), provider, out result); + } +} +#endif diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index 88118b8a..2d7ac38d 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -113,30 +113,34 @@ For example: Condition="@(ReferencePath->AnyHaveMetadataValue('NuGetPackageId', 'System.IO.Compression')) OR @(ReferencePath->AnyHaveMetadataValue('Filename', 'System.IO.Compression'))">$(DefineConstants);FeatureCompression + $(DefineConstants);FeatureNumerics + $(DefineConstants);FeatureAsyncInterfaces $(DefineConstants);FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureAsyncInterfaces;FeatureUnsafe - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression - $(DefineConstants);FeatureValueTuple;FeatureRuntimeInformation;FeatureHttp;FeatureCompression + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces;FeatureUnsafe + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics + $(DefineConstants);FeatureValueTuple;FeatureRuntimeInformation;FeatureHttp;FeatureCompression;FeatureNumerics $(DefineConstants);FeatureValueTuple $(DefineConstants);FeatureValueTuple;FeatureRuntimeInformation $(DefineConstants);FeatureValueTuple;FeatureRuntimeInformation $(DefineConstants);FeatureValueTuple;FeatureRuntimeInformation - $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureCompression;FeatureAsyncInterfaces - $(DefineConstants);FeatureValueTuple;FeatureRuntimeInformation;FeatureCompression + $(DefineConstants);FeatureMemory;FeatureValueTuple;FeatureValueTask;FeatureRuntimeInformation;FeatureCompression;FeatureNumerics;FeatureAsyncInterfaces + $(DefineConstants);FeatureValueTuple;FeatureRuntimeInformation;FeatureCompression;FeatureNumerics +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net10.0/Numbers/ComplexPolyfill.cs b/src/Split/net10.0/Numbers/ComplexPolyfill.cs new file mode 100644 index 00000000..340f27f6 --- /dev/null +++ b/src/Split/net10.0/Numbers/ComplexPolyfill.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#if FeatureNumerics +namespace Polyfills; +using System; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(Complex) + { + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), provider, out result); + } +} +#endif diff --git a/src/Split/net461/Numbers/BigIntegerPolyfill.cs b/src/Split/net461/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net461/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net462/Numbers/BigIntegerPolyfill.cs b/src/Split/net462/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net462/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net47/Numbers/BigIntegerPolyfill.cs b/src/Split/net47/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net47/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net471/Numbers/BigIntegerPolyfill.cs b/src/Split/net471/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net471/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net472/Numbers/BigIntegerPolyfill.cs b/src/Split/net472/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net472/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net48/Numbers/BigIntegerPolyfill.cs b/src/Split/net48/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net48/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net481/Numbers/BigIntegerPolyfill.cs b/src/Split/net481/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net481/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net5.0/Numbers/BigIntegerPolyfill.cs b/src/Split/net5.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net5.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net6.0/Numbers/BigIntegerPolyfill.cs b/src/Split/net6.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net6.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net7.0/Numbers/BigIntegerPolyfill.cs b/src/Split/net7.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net7.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net7.0/Numbers/ComplexPolyfill.cs b/src/Split/net7.0/Numbers/ComplexPolyfill.cs new file mode 100644 index 00000000..340f27f6 --- /dev/null +++ b/src/Split/net7.0/Numbers/ComplexPolyfill.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#if FeatureNumerics +namespace Polyfills; +using System; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(Complex) + { + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), provider, out result); + } +} +#endif diff --git a/src/Split/net8.0/Numbers/BigIntegerPolyfill.cs b/src/Split/net8.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net8.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net8.0/Numbers/ComplexPolyfill.cs b/src/Split/net8.0/Numbers/ComplexPolyfill.cs new file mode 100644 index 00000000..340f27f6 --- /dev/null +++ b/src/Split/net8.0/Numbers/ComplexPolyfill.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#if FeatureNumerics +namespace Polyfills; +using System; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(Complex) + { + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), provider, out result); + } +} +#endif diff --git a/src/Split/net9.0/Numbers/BigIntegerPolyfill.cs b/src/Split/net9.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/net9.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/net9.0/Numbers/ComplexPolyfill.cs b/src/Split/net9.0/Numbers/ComplexPolyfill.cs new file mode 100644 index 00000000..340f27f6 --- /dev/null +++ b/src/Split/net9.0/Numbers/ComplexPolyfill.cs @@ -0,0 +1,25 @@ +// +#pragma warning disable +#if FeatureNumerics +namespace Polyfills; +using System; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(Complex) + { + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out Complex result) => + Complex.TryParse(Encoding.UTF8.GetString(utf8Text), provider, out result); + } +} +#endif diff --git a/src/Split/netcoreapp2.0/Numbers/BigIntegerPolyfill.cs b/src/Split/netcoreapp2.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/netcoreapp2.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/netcoreapp2.1/Numbers/BigIntegerPolyfill.cs b/src/Split/netcoreapp2.1/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/netcoreapp2.1/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/netcoreapp2.2/Numbers/BigIntegerPolyfill.cs b/src/Split/netcoreapp2.2/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/netcoreapp2.2/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/netcoreapp3.0/Numbers/BigIntegerPolyfill.cs b/src/Split/netcoreapp3.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/netcoreapp3.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/netcoreapp3.1/Numbers/BigIntegerPolyfill.cs b/src/Split/netcoreapp3.1/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/netcoreapp3.1/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/netstandard2.0/Numbers/BigIntegerPolyfill.cs b/src/Split/netstandard2.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/netstandard2.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/netstandard2.1/Numbers/BigIntegerPolyfill.cs b/src/Split/netstandard2.1/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/netstandard2.1/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Split/uap10.0/Numbers/BigIntegerPolyfill.cs b/src/Split/uap10.0/Numbers/BigIntegerPolyfill.cs new file mode 100644 index 00000000..5b5748be --- /dev/null +++ b/src/Split/uap10.0/Numbers/BigIntegerPolyfill.cs @@ -0,0 +1,60 @@ +// +#pragma warning disable +#if FeatureNumerics && FeatureMemory +namespace Polyfills; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Numerics; +using System.Text; +static partial class Polyfill +{ + extension(BigInteger) + { + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), style, provider); + /// + /// Parses a span of UTF-8 characters into a value. + /// + public static BigInteger Parse(ReadOnlySpan utf8Text, IFormatProvider? provider) => + BigInteger.Parse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, NumberStyles style, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), style, provider, out result); + /// + /// Tries to parse a span of UTF-8 characters into a value. + /// + public static bool TryParse(ReadOnlySpan utf8Text, IFormatProvider? provider, out BigInteger result) => + BigInteger.TryParse(Encoding.UTF8.GetString(utf8Text), NumberStyles.Integer, provider, out result); + } + extension(BigInteger target) + { + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) + { + string result; + if (format.Length == 0) + { + result = target.ToString(null, provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + return Encoding.UTF8.TryGetBytes(result.AsSpan(), utf8Destination, out bytesWritten); + } + } +} +#endif diff --git a/src/Tests/Numbers/BigIntegerPolyfillTests.cs b/src/Tests/Numbers/BigIntegerPolyfillTests.cs new file mode 100644 index 00000000..0e64c085 --- /dev/null +++ b/src/Tests/Numbers/BigIntegerPolyfillTests.cs @@ -0,0 +1,50 @@ +#if FeatureNumerics && FeatureMemory +using System.Numerics; +using System.Text; + +public class BigIntegerPolyfillTests +{ + const string large = "123456789012345678901234567890"; + + [Test] + public async Task Parse() + { + await Assert.That(BigInteger.Parse("123456789012345678901234567890"u8)).IsEqualTo(BigInteger.Parse(large)); + await Assert.That(BigInteger.Parse("-42"u8, CultureInfo.InvariantCulture)).IsEqualTo(new BigInteger(-42)); + await Assert.That(BigInteger.Parse("FF"u8, NumberStyles.HexNumber, CultureInfo.InvariantCulture)) + .IsEqualTo(BigInteger.Parse("FF", NumberStyles.HexNumber, CultureInfo.InvariantCulture)); + await Assert.That(() => BigInteger.Parse("abc"u8)).Throws(); + } + + [Test] + public async Task TryParse() + { + await Assert.That(BigInteger.TryParse("123456789012345678901234567890"u8, out var value)).IsTrue(); + await Assert.That(value).IsEqualTo(BigInteger.Parse(large)); + + await Assert.That(BigInteger.TryParse("-42"u8, CultureInfo.InvariantCulture, out value)).IsTrue(); + await Assert.That(value).IsEqualTo(new BigInteger(-42)); + + await Assert.That(BigInteger.TryParse("1,000"u8, NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out value)).IsTrue(); + await Assert.That(value).IsEqualTo(new BigInteger(1000)); + + await Assert.That(BigInteger.TryParse("abc"u8, out value)).IsFalse(); + } + + [Test] + public async Task TryFormat() + { + var value = BigInteger.Parse(large); + var buffer = new byte[64]; + + await Assert.That(value.TryFormat(buffer, out var written)).IsTrue(); + await Assert.That(Encoding.UTF8.GetString(buffer, 0, written)).IsEqualTo(large); + + await Assert.That(value.TryFormat(buffer, out written, "N0", CultureInfo.InvariantCulture)).IsTrue(); + await Assert.That(Encoding.UTF8.GetString(buffer, 0, written)).IsEqualTo(value.ToString("N0", CultureInfo.InvariantCulture)); + + await Assert.That(value.TryFormat(new byte[2], out written)).IsFalse(); + await Assert.That(written).IsEqualTo(0); + } +} +#endif diff --git a/src/Tests/Numbers/ComplexPolyfillTests.cs b/src/Tests/Numbers/ComplexPolyfillTests.cs new file mode 100644 index 00000000..a872c56c --- /dev/null +++ b/src/Tests/Numbers/ComplexPolyfillTests.cs @@ -0,0 +1,24 @@ +#if FeatureNumerics && NET7_0_OR_GREATER +using System.Numerics; +using System.Text; + +public class ComplexPolyfillTests +{ + static readonly Complex expected = new(1.5, -2.25); + + static byte[] ExpectedUtf8() => + Encoding.UTF8.GetBytes(expected.ToString(CultureInfo.InvariantCulture)); + + [Test] + public async Task TryParse() + { + await Assert.That(Complex.TryParse(ExpectedUtf8(), CultureInfo.InvariantCulture, out var value)).IsTrue(); + await Assert.That(value).IsEqualTo(expected); + + await Assert.That(Complex.TryParse(ExpectedUtf8(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out value)).IsTrue(); + await Assert.That(value).IsEqualTo(expected); + + await Assert.That(Complex.TryParse("abc"u8, CultureInfo.InvariantCulture, out value)).IsFalse(); + } +} +#endif