Use some generic math in assert code

This commit is contained in:
Alex Barney 2022-12-10 11:33:21 -07:00
parent b7625af148
commit 4108a6c149
2 changed files with 28 additions and 132 deletions

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using LibHac.Common; using LibHac.Common;
using LibHac.Diag.Impl; using LibHac.Diag.Impl;
@ -499,8 +500,7 @@ public static class Assert
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] [CallerLineNumber] int lineNumber = 0)
int lineNumber = 0)
where T : class where T : class
{ {
NullImpl(AssertionType.UserAssert, value, valueText, functionName, fileName, lineNumber); NullImpl(AssertionType.UserAssert, value, valueText, functionName, fileName, lineNumber);
@ -664,11 +664,12 @@ public static class Assert
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// In range int // In range T
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
private static void InRangeImpl(AssertionType assertionType, int value, int lower, int upper, string valueText, private static void InRangeImpl<T>(AssertionType assertionType, T value, T lower, T upper, string valueText,
string lowerText, string upperText, string functionName, string fileName, int lineNumber) string lowerText, string upperText, string functionName, string fileName, int lineNumber)
where T : IComparisonOperators<T, T, bool>
{ {
if (AssertImpl.WithinRange(value, lower, upper)) if (AssertImpl.WithinRange(value, lower, upper))
return; return;
@ -678,103 +679,54 @@ public static class Assert
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
public static void InRange(int value, int lowerInclusive, int upperExclusive, public static void InRange<T>(T value, T lowerInclusive, T upperExclusive,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "", [CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "",
[CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "", [CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IComparisonOperators<T, T, bool>
{ {
InRangeImpl(AssertionType.UserAssert, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText, InRangeImpl(AssertionType.UserAssert, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText,
upperExclusiveText, functionName, fileName, lineNumber); upperExclusiveText, functionName, fileName, lineNumber);
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
internal static void SdkInRange(int value, int lowerInclusive, int upperExclusive, internal static void SdkInRange<T>(T value, T lowerInclusive, T upperExclusive,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "", [CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "",
[CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "", [CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IComparisonOperators<T, T, bool>
{ {
InRangeImpl(AssertionType.SdkAssert, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText, InRangeImpl(AssertionType.SdkAssert, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText,
upperExclusiveText, functionName, fileName, lineNumber); upperExclusiveText, functionName, fileName, lineNumber);
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
internal static void SdkRequiresInRange(int value, int lowerInclusive, int upperExclusive, internal static void SdkRequiresInRange<T>(T value, T lowerInclusive, T upperExclusive,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "", [CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "",
[CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "", [CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IComparisonOperators<T, T, bool>
{ {
InRangeImpl(AssertionType.SdkRequires, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText, InRangeImpl(AssertionType.SdkRequires, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText,
upperExclusiveText, functionName, fileName, lineNumber); upperExclusiveText, functionName, fileName, lineNumber);
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// In range long // Within min-max T
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
private static void InRangeImpl(AssertionType assertionType, long value, long lower, long upper, string valueText, private static void WithinMinMaxImpl<T>(AssertionType assertionType, T value, T min, T max, string valueText,
string lowerText, string upperText, string functionName, string fileName, int lineNumber)
{
if (AssertImpl.WithinRange(value, lower, upper))
return;
AssertImpl.InvokeAssertionInRange(assertionType, value, lower, upper, valueText, lowerText, upperText, functionName,
fileName, lineNumber);
}
[Conditional(AssertCondition)]
public static void InRange(long value, long lowerInclusive, long upperExclusive,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "",
[CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
InRangeImpl(AssertionType.UserAssert, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText,
upperExclusiveText, functionName, fileName, lineNumber);
}
[Conditional(AssertCondition)]
internal static void SdkInRange(long value, long lowerInclusive, long upperExclusive,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "",
[CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
InRangeImpl(AssertionType.SdkAssert, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText,
upperExclusiveText, functionName, fileName, lineNumber);
}
[Conditional(AssertCondition)]
internal static void SdkRequiresInRange(long value, long lowerInclusive, long upperExclusive,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(lowerInclusive))] string lowerInclusiveText = "",
[CallerArgumentExpression(nameof(upperExclusive))] string upperExclusiveText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
InRangeImpl(AssertionType.SdkRequires, value, lowerInclusive, upperExclusive, valueText, lowerInclusiveText,
upperExclusiveText, functionName, fileName, lineNumber);
}
// ---------------------------------------------------------------------
// Within min-max int
// ---------------------------------------------------------------------
private static void WithinMinMaxImpl(AssertionType assertionType, int value, int min, int max, string valueText,
string minText, string maxText, string functionName, string fileName, int lineNumber) string minText, string maxText, string functionName, string fileName, int lineNumber)
where T : IComparisonOperators<T, T, bool>
{ {
if (AssertImpl.WithinMinMax(value, min, max)) if (AssertImpl.WithinMinMax(value, min, max))
return; return;
@ -784,92 +736,42 @@ public static class Assert
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
public static void WithinMinMax(int value, int min, int max, public static void WithinMinMax<T>(T value, T min, T max,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(min))] string minText = "", [CallerArgumentExpression(nameof(min))] string minText = "",
[CallerArgumentExpression(nameof(max))] string maxText = "", [CallerArgumentExpression(nameof(max))] string maxText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IComparisonOperators<T, T, bool>
{ {
WithinMinMaxImpl(AssertionType.UserAssert, value, min, max, valueText, minText, maxText, functionName, WithinMinMaxImpl(AssertionType.UserAssert, value, min, max, valueText, minText, maxText, functionName,
fileName, lineNumber); fileName, lineNumber);
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
internal static void SdkWithinMinMax(int value, int min, int max, internal static void SdkWithinMinMax<T>(T value, T min, T max,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(min))] string minText = "", [CallerArgumentExpression(nameof(min))] string minText = "",
[CallerArgumentExpression(nameof(max))] string maxText = "", [CallerArgumentExpression(nameof(max))] string maxText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IComparisonOperators<T, T, bool>
{ {
WithinMinMaxImpl(AssertionType.SdkAssert, value, min, max, valueText, minText, maxText, functionName, WithinMinMaxImpl(AssertionType.SdkAssert, value, min, max, valueText, minText, maxText, functionName,
fileName, lineNumber); fileName, lineNumber);
} }
[Conditional(AssertCondition)] [Conditional(AssertCondition)]
internal static void SdkRequiresWithinMinMax(int value, int min, int max, internal static void SdkRequiresWithinMinMax<T>(T value, T min, T max,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(min))] string minText = "",
[CallerArgumentExpression(nameof(max))] string maxText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
WithinMinMaxImpl(AssertionType.SdkRequires, value, min, max, valueText, minText, maxText, functionName,
fileName, lineNumber);
}
// ---------------------------------------------------------------------
// Within min-max long
// ---------------------------------------------------------------------
private static void WithinMinMaxImpl(AssertionType assertionType, long value, long min, long max,
string valueText, string minText, string maxText, string functionName, string fileName, int lineNumber)
{
if (AssertImpl.WithinMinMax(value, min, max))
return;
AssertImpl.InvokeAssertionWithinMinMax(assertionType, value, min, max, valueText, minText, maxText, functionName,
fileName, lineNumber);
}
[Conditional(AssertCondition)]
public static void WithinMinMax(long value, long min, long max,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(min))] string minText = "",
[CallerArgumentExpression(nameof(max))] string maxText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
WithinMinMaxImpl(AssertionType.UserAssert, value, min, max, valueText, minText, maxText, functionName,
fileName, lineNumber);
}
[Conditional(AssertCondition)]
internal static void SdkWithinMinMax(long value, long min, long max,
[CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(min))] string minText = "",
[CallerArgumentExpression(nameof(max))] string maxText = "",
[CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0)
{
WithinMinMaxImpl(AssertionType.SdkAssert, value, min, max, valueText, minText, maxText, functionName,
fileName, lineNumber);
}
[Conditional(AssertCondition)]
internal static void SdkRequiresWithinMinMax(long value, long min, long max,
[CallerArgumentExpression(nameof(value))] string valueText = "", [CallerArgumentExpression(nameof(value))] string valueText = "",
[CallerArgumentExpression(nameof(min))] string minText = "", [CallerArgumentExpression(nameof(min))] string minText = "",
[CallerArgumentExpression(nameof(max))] string maxText = "", [CallerArgumentExpression(nameof(max))] string maxText = "",
[CallerMemberName] string functionName = "", [CallerMemberName] string functionName = "",
[CallerFilePath] string fileName = "", [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
where T : IComparisonOperators<T, T, bool>
{ {
WithinMinMaxImpl(AssertionType.SdkRequires, value, min, max, valueText, minText, maxText, functionName, WithinMinMaxImpl(AssertionType.SdkRequires, value, min, max, valueText, minText, maxText, functionName,
fileName, lineNumber); fileName, lineNumber);

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using LibHac.Common; using LibHac.Common;
@ -22,8 +23,9 @@ internal static class AssertImpl
$"{valueText} must be nullptr."); $"{valueText} must be nullptr.");
} }
internal static void InvokeAssertionInRange(AssertionType assertionType, long value, long lower, long upper, internal static void InvokeAssertionInRange<T>(AssertionType assertionType, T value, T lower, T upper,
string valueText, string lowerText, string upperText, string functionName, string fileName, int lineNumber) string valueText, string lowerText, string upperText, string functionName, string fileName, int lineNumber)
where T : IComparisonOperators<T, T, bool>
{ {
string message = string message =
string.Format( string.Format(
@ -33,8 +35,9 @@ internal static class AssertImpl
Assert.OnAssertionFailure(assertionType, "RangeCheck", functionName, fileName, lineNumber, message); Assert.OnAssertionFailure(assertionType, "RangeCheck", functionName, fileName, lineNumber, message);
} }
internal static void InvokeAssertionWithinMinMax(AssertionType assertionType, long value, long min, long max, internal static void InvokeAssertionWithinMinMax<T>(AssertionType assertionType, T value, T min, T max,
string valueText, string minText, string maxText, string functionName, string fileName, int lineNumber) string valueText, string minText, string maxText, string functionName, string fileName, int lineNumber)
where T : IComparisonOperators<T, T, bool>
{ {
string message = string message =
string.Format( string.Format(
@ -166,22 +169,13 @@ internal static class AssertImpl
return item.HasValue; return item.HasValue;
} }
public static bool WithinRange(int value, int lowerInclusive, int upperExclusive) public static bool WithinRange<T>(T value, T lowerInclusive, T upperExclusive)
where T : IComparisonOperators<T, T, bool>
{ {
return lowerInclusive <= value && value < upperExclusive; return lowerInclusive <= value && value < upperExclusive;
} }
public static bool WithinRange(long value, long lowerInclusive, long upperExclusive) public static bool WithinMinMax<T>(T value, T min, T max) where T : IComparisonOperators<T, T, bool>
{
return lowerInclusive <= value && value < upperExclusive;
}
public static bool WithinMinMax(int value, int min, int max)
{
return min <= value && value <= max;
}
public static bool WithinMinMax(long value, long min, long max)
{ {
return min <= value && value <= max; return min <= value && value <= max;
} }