Skip to content

Commit

Permalink
catch up the generic math implementations to .NET 7.0 GA
Browse files Browse the repository at this point in the history
  • Loading branch information
smdn committed Jan 5, 2023
1 parent 226796f commit 21de9b5
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 87 deletions.
7 changes: 0 additions & 7 deletions src/FeatureGenericMath.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,4 @@ SPDX-License-Identifier: MIT
<DefineConstants>FEATURE_GENERIC_MATH;$(DefineConstants)</DefineConstants>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>

<ItemGroup Condition="
$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '7.0.0')) and
$(NETCoreSdkVersion.Contains('-preview'))
">
<PackageReference Include="System.Runtime.Experimental" Version="7.0.0-preview.2.22152.2" Condition="$(TargetFramework.StartsWith('net7'))" />
</ItemGroup>
</Project>
10 changes: 5 additions & 5 deletions src/Smdn.Fundamental.MimeType/Smdn/MimeType.IParseable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ partial class MimeType
#pragma warning restore IDE0040
#if FEATURE_GENERIC_MATH
:
ISpanParseable<MimeType>
ISpanParsable<MimeType>
#endif
{
#if OBSOLETE_MEMBER
Expand All @@ -39,7 +39,7 @@ out MimeType? result
)
=> TryParse(s, provider: null, out result);

// IParseable<TSelf>.TryParse
// IParsable<TSelf>.TryParse
public static bool TryParse(
string? s,
IFormatProvider? provider,
Expand Down Expand Up @@ -71,7 +71,7 @@ out var ret
return true;
}

// ISpanParseable<TSelf>.TryParse
// ISpanParsable<TSelf>.TryParse
public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out MimeType result)
{
result = null!;
Expand Down Expand Up @@ -101,7 +101,7 @@ public static (string type, string subType) Parse(string s)
#pragma warning restore SA1316
#endif

// IParseable<TSelf>.Parse
// IParsable<TSelf>.Parse
public static MimeType Parse(string s, IFormatProvider? provider = null)
{
TryParse(
Expand All @@ -115,7 +115,7 @@ out var result
return new(result.Type, result.SubType);
}

// ISpanParseable<TSelf>.Parse
// ISpanParsable<TSelf>.Parse
public static MimeType Parse(ReadOnlySpan<char> s, IFormatProvider? provider = null)
{
TryParse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ partial struct Node
#pragma warning restore IDE0040
#if FEATURE_GENERIC_MATH
:
IParseable<Node>,
ISpanParseable<Node>
IParsable<Node>,
ISpanParsable<Node>
#endif
{
public static Node Parse(string s, IFormatProvider? provider = null)
Expand Down Expand Up @@ -64,7 +64,7 @@ public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out

if (
!byte.TryParse(
span.ToParseableType(),
span.ToParsableType(),
NumberStyles.HexNumber,
provider: null,
out var parsed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static
#else
string
#endif
ToParseableType(this ReadOnlySpan<char> s)
ToParsableType(this ReadOnlySpan<char> s)
#if SYSTEM_INT32_TRYPARSE_READONLYSPAN_OF_CHAR
=> s;
#else
Expand Down
26 changes: 13 additions & 13 deletions src/Smdn.Fundamental.Uuid/Smdn/Uuid.IParseable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ partial struct Uuid
#pragma warning restore IDE0040
#if FEATURE_GENERIC_MATH
:
IParseable<Uuid>,
ISpanParseable<Uuid>
IParsable<Uuid>,
ISpanParsable<Uuid>
#endif
{
private enum TryParseResult {
Expand Down Expand Up @@ -80,36 +80,36 @@ static bool TryGetSpanUpToNextDelimiter(ref ReadOnlySpan<char> span, char delimi

if (!TryGetSpanUpToNextDelimiter(ref s, delimiter, out var fieldTimeLow))
return TryParseResult.FormatError;
if (!(fieldTimeLow.Length == 8 && uint.TryParse(fieldTimeLow.ToParseableType(), NumberStyles.HexNumber, provider: null, out var fieldValueTimeLow)))
if (!(fieldTimeLow.Length == 8 && uint.TryParse(fieldTimeLow.ToParsableType(), NumberStyles.HexNumber, provider: null, out var fieldValueTimeLow)))
return TryParseResult.FormatErrorOnTimeLow;

if (!TryGetSpanUpToNextDelimiter(ref s, delimiter, out var fieldTimeMid))
return TryParseResult.FormatError;
if (!(fieldTimeMid.Length == 4 && ushort.TryParse(fieldTimeMid.ToParseableType(), NumberStyles.HexNumber, provider: null, out var fieldValueTimeMid)))
if (!(fieldTimeMid.Length == 4 && ushort.TryParse(fieldTimeMid.ToParsableType(), NumberStyles.HexNumber, provider: null, out var fieldValueTimeMid)))
return TryParseResult.FormatErrorOnTimeMid;

if (!TryGetSpanUpToNextDelimiter(ref s, delimiter, out var fieldTimeHighAndVersion))
return TryParseResult.FormatError;
if (!(fieldTimeHighAndVersion.Length == 4 && ushort.TryParse(fieldTimeHighAndVersion.ToParseableType(), NumberStyles.HexNumber, provider: null, out var fieldValueTimeHiAndVersion)))
if (!(fieldTimeHighAndVersion.Length == 4 && ushort.TryParse(fieldTimeHighAndVersion.ToParsableType(), NumberStyles.HexNumber, provider: null, out var fieldValueTimeHiAndVersion)))
return TryParseResult.FormatErrorOnTimeHiAndVersion;

if (!TryGetSpanUpToNextDelimiter(ref s, delimiter, out var fieldClockSeq))
return TryParseResult.FormatError;
if (fieldClockSeq.Length != 4)
return TryParseResult.FormatErrorOnClockSeqHiAndReserved;
if (!byte.TryParse(fieldClockSeq.Slice(0, 2).ToParseableType(), NumberStyles.HexNumber, null, out var fieldValueClockSeqHiAndReserved))
if (!byte.TryParse(fieldClockSeq.Slice(0, 2).ToParsableType(), NumberStyles.HexNumber, null, out var fieldValueClockSeqHiAndReserved))
return TryParseResult.FormatErrorOnClockSeqHiAndReserved;
if (!byte.TryParse(fieldClockSeq.Slice(2, 2).ToParseableType(), NumberStyles.HexNumber, null, out var fieldValueClockSeqLow))
if (!byte.TryParse(fieldClockSeq.Slice(2, 2).ToParsableType(), NumberStyles.HexNumber, null, out var fieldValueClockSeqLow))
return TryParseResult.FormatErrorOnClockSeqLow;

if (
!(
byte.TryParse(s.Slice(0, 2).ToParseableType(), NumberStyles.HexNumber, null, out var n0) &&
byte.TryParse(s.Slice(2, 2).ToParseableType(), NumberStyles.HexNumber, null, out var n1) &&
byte.TryParse(s.Slice(4, 2).ToParseableType(), NumberStyles.HexNumber, null, out var n2) &&
byte.TryParse(s.Slice(6, 2).ToParseableType(), NumberStyles.HexNumber, null, out var n3) &&
byte.TryParse(s.Slice(8, 2).ToParseableType(), NumberStyles.HexNumber, null, out var n4) &&
byte.TryParse(s.Slice(10, 2).ToParseableType(), NumberStyles.HexNumber, null, out var n5)
byte.TryParse(s.Slice(0, 2).ToParsableType(), NumberStyles.HexNumber, null, out var n0) &&
byte.TryParse(s.Slice(2, 2).ToParsableType(), NumberStyles.HexNumber, null, out var n1) &&
byte.TryParse(s.Slice(4, 2).ToParsableType(), NumberStyles.HexNumber, null, out var n2) &&
byte.TryParse(s.Slice(6, 2).ToParsableType(), NumberStyles.HexNumber, null, out var n3) &&
byte.TryParse(s.Slice(8, 2).ToParsableType(), NumberStyles.HexNumber, null, out var n4) &&
byte.TryParse(s.Slice(10, 2).ToParsableType(), NumberStyles.HexNumber, null, out var n5)
)
) {
return TryParseResult.FormatErrorOnNode;
Expand Down
32 changes: 16 additions & 16 deletions tests/Smdn.Fundamental.MimeType/Smdn/MimeType.IParseable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,40 +53,40 @@ public void TryParse_ReadOnlySpanOfChar(string s, MimeType expected)

#if FEATURE_GENERIC_MATH
[TestCaseSource(nameof(YieldParseValidTestCases))]
public void IParseable_Parse(string s, MimeType expected)
public void IParsable_Parse(string s, MimeType expected)
{
Assert.AreEqual(expected, Parse<MimeType>(s));

static TSelf Parse<TSelf>(string s) where TSelf : IParseable<TSelf>
static TSelf Parse<TSelf>(string s) where TSelf : IParsable<TSelf>
=> TSelf.Parse(s, provider: null);
}

[TestCaseSource(nameof(YieldParseValidTestCases))]
public void ISpanParseable_Parse(string s, MimeType expected)
public void ISpanParsable_Parse(string s, MimeType expected)
{
Assert.AreEqual(expected, Parse<MimeType>(s.AsSpan()));

static TSelf Parse<TSelf>(ReadOnlySpan<char> s) where TSelf : ISpanParseable<TSelf>
static TSelf Parse<TSelf>(ReadOnlySpan<char> s) where TSelf : ISpanParsable<TSelf>
=> TSelf.Parse(s, provider: null);
}

[TestCaseSource(nameof(YieldParseValidTestCases))]
public void IParseable_TryParse(string s, MimeType expected)
public void IParsable_TryParse(string s, MimeType expected)
{
Assert.IsTrue(TryParse<MimeType>(s, out var result));
Assert.AreEqual(expected, result);

static bool TryParse<TSelf>(string s, out TSelf result) where TSelf : IParseable<TSelf>
static bool TryParse<TSelf>(string s, out TSelf result) where TSelf : IParsable<TSelf>
=> TSelf.TryParse(s, provider: null, out result);
}

[TestCaseSource(nameof(YieldParseValidTestCases))]
public void ISpanParseable_TryParse(string s, MimeType expected)
public void ISpanParsable_TryParse(string s, MimeType expected)
{
Assert.IsTrue(TryParse<MimeType>(s.AsSpan(), out var result));
Assert.AreEqual(expected, result);

static bool TryParse<TSelf>(ReadOnlySpan<char> s, out TSelf result) where TSelf : ISpanParseable<TSelf>
static bool TryParse<TSelf>(ReadOnlySpan<char> s, out TSelf result) where TSelf : ISpanParsable<TSelf>
=> TSelf.TryParse(s, provider: null, out result);
}
#endif
Expand Down Expand Up @@ -119,47 +119,47 @@ public void TryParse_ReadOnlySpanOfChar_InvalidFormat(string s, Type discard)

#if FEATURE_GENERIC_MATH
[TestCaseSource(nameof(YieldParseInvalidFormatTestCases))]
public void IParseable_Parse_InvalidFormat(string s, Type expectedExceptionType)
public void IParsable_Parse_InvalidFormat(string s, Type expectedExceptionType)
{
Assert.Throws(expectedExceptionType, () => Parse<MimeType>(s));

static TSelf Parse<TSelf>(string s) where TSelf : IParseable<TSelf>
static TSelf Parse<TSelf>(string s) where TSelf : IParsable<TSelf>
=> TSelf.Parse(s, provider: null);
}

[TestCaseSource(nameof(YieldParseInvalidFormatTestCases))]
public void ISpanParseable_Parse_InvalidFormat(string s, Type expectedExceptionType)
public void ISpanParsable_Parse_InvalidFormat(string s, Type expectedExceptionType)
{
if (s is null)
Assert.Pass();

Assert.Throws(expectedExceptionType, () => Parse<MimeType>(s.AsSpan()));

static TSelf Parse<TSelf>(ReadOnlySpan<char> s) where TSelf : ISpanParseable<TSelf>
static TSelf Parse<TSelf>(ReadOnlySpan<char> s) where TSelf : ISpanParsable<TSelf>
=> TSelf.Parse(s, provider: null);
}

[TestCaseSource(nameof(YieldParseInvalidFormatTestCases))]
public void IParseable_TryParse_InvalidFormat(string s, Type discard)
public void IParsable_TryParse_InvalidFormat(string s, Type discard)
{
if (s is null)
Assert.Pass();

Assert.IsFalse(TryParse<MimeType>(s, out _));

static bool TryParse<TSelf>(string s, out TSelf result) where TSelf : IParseable<TSelf>
static bool TryParse<TSelf>(string s, out TSelf result) where TSelf : IParsable<TSelf>
=> TSelf.TryParse(s, provider: null, out result);
}

[TestCaseSource(nameof(YieldParseInvalidFormatTestCases))]
public void ISpanParseable_TryParse_InvalidFormat(string s, Type discard)
public void ISpanParsable_TryParse_InvalidFormat(string s, Type discard)
{
if (s is null)
Assert.Pass();

Assert.IsFalse(TryParse<MimeType>(s.AsSpan(), out _));

static bool TryParse<TSelf>(ReadOnlySpan<char> s, out TSelf result) where TSelf : ISpanParseable<TSelf>
static bool TryParse<TSelf>(ReadOnlySpan<char> s, out TSelf result) where TSelf : ISpanParsable<TSelf>
=> TSelf.TryParse(s, provider: null, out result);
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ public void TestParse_ArgumentNull()
Assert.Throws<ArgumentNullException>(() => Node.Parse((string)null!, provider: null));

#if FEATURE_GENERIC_MATH
Assert.Throws<ArgumentNullException>(() => Parse<Node>(null, provider: null), "IParseable");
Assert.Throws<ArgumentNullException>(() => Parse<Node>(null, provider: null), "IParsable");

static T Parse<T>(string s, IFormatProvider provider) where T : IParseable<T> => T.Parse(s, provider);
static T Parse<T>(string s, IFormatProvider provider) where T : IParsable<T> => T.Parse(s, provider);
#endif
}

Expand Down Expand Up @@ -48,16 +48,16 @@ public void TestParse(string s, bool expectValid, string expectedString)

#if FEATURE_GENERIC_MATH
if (expectValid)
Assert.DoesNotThrow(() => n = Parse<Node>(s, provider: null), "IParseable");
Assert.DoesNotThrow(() => n = Parse<Node>(s, provider: null), "IParsable");
else
Assert.Throws<FormatException>(() => n = Parse<Node>(s, provider: null), "IParseable");
Assert.Throws<FormatException>(() => n = Parse<Node>(s, provider: null), "IParsable");

if (expectValid) {
Assert.AreEqual(expectedString.ToUpperInvariant(), n.ToString("X"), "IParseable");
Assert.AreEqual(expectedString.ToLowerInvariant(), n.ToString("x"), "IParseable");
Assert.AreEqual(expectedString.ToUpperInvariant(), n.ToString("X"), "IParsable");
Assert.AreEqual(expectedString.ToLowerInvariant(), n.ToString("x"), "IParsable");
}

static T Parse<T>(string s, IFormatProvider provider) where T : IParseable<T> => T.Parse(s, provider);
static T Parse<T>(string s, IFormatProvider provider) where T : IParsable<T> => T.Parse(s, provider);
#endif
}

Expand All @@ -75,7 +75,7 @@ public void TestParse(string s, bool expectValid, string expectedString)
[TestCase("00:00:00:00:00:0X", false, null)]
[TestCase("00-00-00-00-00-00", false, null)]
[TestCase("00:00:00:00:00-00", false, null)]
public void TestParse_ISpanParseable(string s, bool expectValid, string expectedString)
public void TestParse_ISpanParsable(string s, bool expectValid, string expectedString)
{
Node n = default;

Expand All @@ -91,16 +91,16 @@ public void TestParse_ISpanParseable(string s, bool expectValid, string expected

#if FEATURE_GENERIC_MATH
if (expectValid)
Assert.DoesNotThrow(() => n = Parse<Node>(s.AsSpan(), provider: null), "IParseable");
Assert.DoesNotThrow(() => n = Parse<Node>(s.AsSpan(), provider: null), "IParsable");
else
Assert.Throws<FormatException>(() => n = Parse<Node>(s.AsSpan(), provider: null), "IParseable");
Assert.Throws<FormatException>(() => n = Parse<Node>(s.AsSpan(), provider: null), "IParsable");

if (expectValid) {
Assert.AreEqual(expectedString.ToUpperInvariant(), n.ToString("X"), "IParseable");
Assert.AreEqual(expectedString.ToLowerInvariant(), n.ToString("x"), "IParseable");
Assert.AreEqual(expectedString.ToUpperInvariant(), n.ToString("X"), "IParsable");
Assert.AreEqual(expectedString.ToLowerInvariant(), n.ToString("x"), "IParsable");
}

static T Parse<T>(ReadOnlySpan<char> s, IFormatProvider provider) where T : ISpanParseable<T> => T.Parse(s, provider);
static T Parse<T>(ReadOnlySpan<char> s, IFormatProvider provider) where T : ISpanParsable<T> => T.Parse(s, provider);
#endif
}

Expand Down Expand Up @@ -129,14 +129,14 @@ public void TestTryParse(string s, bool expectValid, string expectedString)
}

#if FEATURE_GENERIC_MATH
Assert.AreEqual(expectValid, TryParse<Node>(s, out var node2), "IParseable");
Assert.AreEqual(expectValid, TryParse<Node>(s, out var node2), "IParsable");

if (expectValid) {
Assert.AreEqual(expectedString.ToUpperInvariant(), node2.ToString("X"), "IParseable");
Assert.AreEqual(expectedString.ToLowerInvariant(), node2.ToString("x"), "IParseable");
Assert.AreEqual(expectedString.ToUpperInvariant(), node2.ToString("X"), "IParsable");
Assert.AreEqual(expectedString.ToLowerInvariant(), node2.ToString("x"), "IParsable");
}

static bool TryParse<T>(string s, out T result) where T : IParseable<T> => T.TryParse(s, provider: null, out result);
static bool TryParse<T>(string s, out T result) where T : IParsable<T> => T.TryParse(s, provider: null, out result);
#endif
}

Expand All @@ -155,7 +155,7 @@ public void TestTryParse(string s, bool expectValid, string expectedString)
[TestCase("00:00:00:00:00:0X", false, null)]
[TestCase("00-00-00-00-00-00", false, null)]
[TestCase("00:00:00:00:00-00", false, null)]
public void TestTryParse_ISpanParseable(string s, bool expectValid, string expectedString)
public void TestTryParse_ISpanParsable(string s, bool expectValid, string expectedString)
{
Assert.AreEqual(expectValid, Node.TryParse(s.AsSpan(), out var node));

Expand All @@ -165,14 +165,14 @@ public void TestTryParse_ISpanParseable(string s, bool expectValid, string expec
}

#if FEATURE_GENERIC_MATH
Assert.AreEqual(expectValid, TryParse<Node>(s.AsSpan(), out var node2), "IParseable");
Assert.AreEqual(expectValid, TryParse<Node>(s.AsSpan(), out var node2), "IParsable");

if (expectValid) {
Assert.AreEqual(expectedString.ToUpperInvariant(), node2.ToString("X"), "IParseable");
Assert.AreEqual(expectedString.ToLowerInvariant(), node2.ToString("x"), "IParseable");
Assert.AreEqual(expectedString.ToUpperInvariant(), node2.ToString("X"), "IParsable");
Assert.AreEqual(expectedString.ToLowerInvariant(), node2.ToString("x"), "IParsable");
}

static bool TryParse<T>(ReadOnlySpan<char> s, out T result) where T : ISpanParseable<T> => T.TryParse(s, provider: null, out result);
static bool TryParse<T>(ReadOnlySpan<char> s, out T result) where T : ISpanParsable<T> => T.TryParse(s, provider: null, out result);
#endif
}
}
Loading

0 comments on commit 21de9b5

Please sign in to comment.