-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Guard APIs #3131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
michael-hawker
merged 128 commits into
CommunityToolkit:master
from
Sergio0694:feature/guard-apis
Mar 15, 2020
Merged
Guard APIs #3131
Changes from 1 commit
Commits
Show all changes
128 commits
Select commit
Hold shift + click to select a range
1c79157
Initial guard APIs added
Sergio0694 0554d2f
Added EqualTo and NotEqualTo APIs
Sergio0694 6dc701f
Merge branch 'master' into feature/guard-apis
Sergio0694 018e5c4
Added more Guard APIs
Sergio0694 8d78ba3
New interval Guard APIs added
Sergio0694 0b76fb9
Added Guard APIs for IEnumerable<T> values
Sergio0694 8028741
Renamed APIs
Sergio0694 cd23275
Added Guard APIs for Stream values
Sergio0694 a54441c
Added Guard APIs for ReadOnlySpan<T> values
Sergio0694 8dee59a
Added Guard APIs for ReadOnlyMemory<T> values
Sergio0694 2d32333
Code refactoring
Sergio0694 19e3bcc
Minor code refactoring
Sergio0694 0ff1f00
Added Guard.IsBitwiseEqualTo<T> API
Sergio0694 9dd8a80
Added Guard.IsNull API
Sergio0694 f2a4500
Code refactoring and optimizations
Sergio0694 b79daa7
Code refactoring
Sergio0694 d44e633
Added Guard.HasSizeNotEqualTo<T> API
Sergio0694 0292f9d
Added Guard size API overloads for the string type
Sergio0694 073a205
Added Guard size API overloads for T[] arrays
Sergio0694 5edef16
Code refactoring
Sergio0694 1a19fea
Removed unnecessary using directives
Sergio0694 d38ad13
Added Guard reference check APIs
Sergio0694 e9108fc
Added new Guaard APIs for string values
Sergio0694 18bb2d4
Improved Guard.IsBitwiseEqualTo<T> API
Sergio0694 2d9536f
Improved Guard.IsNull APIs
Sergio0694 a927dad
Added new size APIs for copy operations
Sergio0694 56a3a18
Added new type test APIs, minor code tweaks
Sergio0694 bbd10a8
Minor bug fixes
Sergio0694 fbb5801
Added Guard APIs for Task values
Sergio0694 eba232e
Minor code tweak
Sergio0694 9071e12
Added new Guard.IsEmpty APIs
Sergio0694 edb1d41
Refactored code to remove unsafe requirement
Sergio0694 d9c83f4
Added Guard.IsInRange<T> APIs
Sergio0694 e63402b
Added missing type checks in Guard.IsBitwiseEqualTo API
Sergio0694 87056c9
Added ValueTypeExtensions.ToHexString API
Sergio0694 0d34c0a
Code refactoring
Sergio0694 497d149
Added ValueTypeExtensions tests
Sergio0694 bc0fc1b
Added general Guard tests
Sergio0694 606cbde
Bug fixes in the Guard class
Sergio0694 f29cd93
Minor speed improvements
Sergio0694 79d2dd4
Code refactoring
Sergio0694 793c769
Removed unnecessary using directives
Sergio0694 8e2f2d8
More speed improvements and API refactoring
Sergio0694 5b58e5e
Refactored/fixed some Guard APIs
Sergio0694 b664c90
More bug fixes
Sergio0694 7f65184
Added Guard tests for array APIs
Sergio0694 4304edd
Fixed the Guard.IsNotEmpty<T> array API
Sergio0694 4802936
Moved exception throwers to separate class
Sergio0694 ed5315a
Moved general Guard throwers to separate class
Sergio0694 1772a0f
Disabled warning for XML overload resolution
Sergio0694 9814d91
Moved array Guard throwers to separate class
Sergio0694 1b78344
Moved stream Guard throwers to separate class
Sergio0694 bc0dc18
Fixed some XML docs
Sergio0694 e000fe0
Moved enumerable Guard throwers to separate class
Sergio0694 21cf16a
Moved task Guard throwers to separate class
Sergio0694 c1b9c8b
Added new Guard APIs for tasks
Sergio0694 c784d4e
Moved string Guard throwers to separate class
Sergio0694 8cf87c3
Moved ReadOnlySpan<T> Guard throwers to separate class
Sergio0694 24e03f5
Added Span<T> APIs to the Guard class
Sergio0694 6f1679b
Moved ReadOnlyMemory<T> Guard throwers to separate class
Sergio0694 7e80e43
Added Memory<T> APIs to the Guard class
Sergio0694 662bb83
Minor code refactoring
Sergio0694 1c334df
Update file headers
Sergio0694 eccc2a6
Removed unnecessary methods
Sergio0694 15ef6a3
Added TypeExtensions.ToTypeString extension
Sergio0694 317fc99
Improved error messages for general Guard APIs
Sergio0694 cb1f3b0
Improved error messages for Enumerable Guard APIs
Sergio0694 23f1504
Improved error messages for stream Guard APIs
Sergio0694 920e69f
Improved error messages for array Guard APIs
Sergio0694 18e661f
Improved error messages for string Guard APIs
Sergio0694 d00e0e3
Improved error messages for task Guard APIs
Sergio0694 6aeedaa
Improved error messages for span Guard APIs
Sergio0694 acafd8a
Improved error messages for memory Guard APIs
Sergio0694 8c7757a
Improved type string for nullable types
Sergio0694 c2fd97c
Improved type string for value tuple types
Sergio0694 8facb7e
Minor performance improvement
Sergio0694 2952e23
Added numeric comparison T4 file
Sergio0694 4991a5c
Updated .gitignore to skip generated files
Sergio0694 714cf31
Moved comparison Guard APIs to separate file
Sergio0694 fa8cc56
Renamed template file, fixed incorrect XML doc
Sergio0694 effb2ed
Fixed missing blank line
Sergio0694 e2e5171
Removed unnecessary type parameters
Sergio0694 4482217
Moved enumerable Guard APIs to separate file
Sergio0694 94872b9
Code refactoring in the enumerable T4 template
Sergio0694 756c842
Renamed a file
Sergio0694 0ecef12
Added empty template for ThrowHelper.Collection
Sergio0694 e093427
Code refactoring in the T4 templates
Sergio0694 9db9cd0
Switched collection throw helpers to T4 generation
Sergio0694 f6e3248
Code refactoring
Sergio0694 deb302b
Merge pull request #7 from Sergio0694/feature/guard-apis-T4
Sergio0694 fcc3c05
Removed incorrect file header
Sergio0694 760972f
Added new Guard.IsInRangeFor API
Sergio0694 8d6cc8a
Updated .gitignore, added generated files to source control
Sergio0694 e3d245f
Added tests for Guard.IsInRangeFor
Sergio0694 d367add
Improved formatting of values in error messages
Sergio0694 6d97f33
Improved error messages
Sergio0694 ec67152
More improvements to the error messages
Sergio0694 b2c3acb
Minor code tweaks
Sergio0694 43b22f0
Added Guard.IsNotOfType APIs
Sergio0694 c8af095
Added Guard.IsNotAssignableToType APIs
Sergio0694 7adfa79
Added Guard.IsDefault<T> APIs
Sergio0694 95b9fd1
Merge branch 'master' into feature/guard-apis
Sergio0694 d4c2d05
Fixed some XML docs
Sergio0694 afd973e
Added missing [Pure] attribute
Sergio0694 96ce238
Fixed typo in a comment
Sergio0694 cb98a02
Removed unnecessary comment after code changes
Sergio0694 5f25e18
Added XML comment for the T4 service
Sergio0694 cf5785c
Added more comments to ToHexString
Sergio0694 801dc93
Suppressed an incorrect code style warning
Sergio0694 b840201
Added more tests for Guard.IsInRange
Sergio0694 818c1eb
Added Guard.IsNotInRangeFor APIs
Sergio0694 caad2f7
Added readme file for the T4 templates
Sergio0694 7134f98
Changed generated files extension to .g.cs to avoid conflicts
Sergio0694 01a7257
Added Guard.IsCloseTo and Guard.IsNotCloseTo APIs
Sergio0694 f33c984
Added tests for IsCloseTo
Sergio0694 1b0f2c9
Updated ".g.cs" extension for generated files
Sergio0694 ef189ba
Removed extra space (typo)
Sergio0694 ac44dad
More tweakes to the Guard.md file
Sergio0694 21115f6
Excluded TypeInfo.g.cs file from .ttinclude from checkout
Sergio0694 67fcd47
Added more info about target ranges for some APIs
Sergio0694 41fea84
Added IsCloseTo overloads for long type
Sergio0694 132d240
Minor code tweaks
Sergio0694 f17aacd
Added comment to describe (uint) cast range check trick
Sergio0694 949134b
Added a nore about the .g.cs files being checked in
Sergio0694 c9283d1
Merge branch 'master' into feature/guard-apis
michael-hawker de701b6
Merge branch 'master' into feature/guard-apis
Sergio0694 51b45e2
Fixed IsCloseTo tests
Sergio0694 244da99
Fixed IsNull tests
Sergio0694 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Added Guard.IsCloseTo and Guard.IsNotCloseTo APIs
- Loading branch information
commit 01a725711e4b03e2600d980e084633249b40e9ab
There are no files selected for viewing
127 changes: 127 additions & 0 deletions
127
Microsoft.Toolkit/Diagnostics/Guard.Comparable.Numeric.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| #nullable enable | ||
|
|
||
| namespace Microsoft.Toolkit.Diagnostics | ||
| { | ||
| /// <summary> | ||
| /// Helper methods to verify conditions when running code. | ||
| /// </summary> | ||
| public static partial class Guard | ||
| { | ||
| /// <summary> | ||
| /// Asserts that the input value must be within a given distance from a specified value. | ||
| /// </summary> | ||
| /// <param name="value">The input <see cref="int"/> value to test.</param> | ||
| /// <param name="target">The target <see cref="int"/> value to test for.</param> | ||
| /// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param> | ||
| /// <param name="name">The name of the input parameter being tested.</param> | ||
| /// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) > <paramref name="delta"/>.</exception> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static void IsCloseTo(int value, int target, int delta, string name) | ||
| { | ||
| /* Cast to long before calculating the difference to avoid overflows | ||
Sergio0694 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * when the values are at the two extremes of the supported range. | ||
| * Then cast to double to calculate the absolute value: this allows | ||
| * the JIT compiler to use AVX instructions on X64 CPUs instead of | ||
| * conditional jumps, which results in more efficient assembly code. | ||
| * The IEEE 754 specs guarantees that a 32 bit integer value can | ||
| * be stored within a double precision floating point value with | ||
| * no loss of precision, so the result will always be correct here. */ | ||
| if (Math.Abs((double)((long)value - target)) > delta) | ||
| { | ||
| ThrowHelper.ThrowArgumentExceptionForIsCloseTo(value, target, delta, name); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Asserts that the input value must not be within a given distance from a specified value. | ||
| /// </summary> | ||
| /// <param name="value">The input <see cref="int"/> value to test.</param> | ||
| /// <param name="target">The target <see cref="int"/> value to test for.</param> | ||
| /// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param> | ||
| /// <param name="name">The name of the input parameter being tested.</param> | ||
| /// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) <= <paramref name="delta"/>.</exception> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static void IsNotCloseTo(int value, int target, int delta, string name) | ||
| { | ||
| if (Math.Abs((double)((long)value - target)) <= delta) | ||
| { | ||
| ThrowHelper.ThrowArgumentExceptionForIsNotCloseTo(value, target, delta, name); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Asserts that the input value must be within a given distance from a specified value. | ||
| /// </summary> | ||
| /// <param name="value">The input <see cref="float"/> value to test.</param> | ||
| /// <param name="target">The target <see cref="float"/> value to test for.</param> | ||
| /// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param> | ||
| /// <param name="name">The name of the input parameter being tested.</param> | ||
| /// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) > <paramref name="delta"/>.</exception> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static void IsCloseTo(float value, float target, float delta, string name) | ||
| { | ||
| if (Math.Abs(value - target) > delta) | ||
| { | ||
| ThrowHelper.ThrowArgumentExceptionForIsCloseTo(value, target, delta, name); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Asserts that the input value must not be within a given distance from a specified value. | ||
| /// </summary> | ||
| /// <param name="value">The input <see cref="float"/> value to test.</param> | ||
| /// <param name="target">The target <see cref="float"/> value to test for.</param> | ||
| /// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param> | ||
| /// <param name="name">The name of the input parameter being tested.</param> | ||
| /// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) <= <paramref name="delta"/>.</exception> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static void IsNotCloseTo(float value, float target, float delta, string name) | ||
| { | ||
| if (Math.Abs(value - target) <= delta) | ||
| { | ||
| ThrowHelper.ThrowArgumentExceptionForIsNotCloseTo(value, target, delta, name); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Asserts that the input value must be within a given distance from a specified value. | ||
| /// </summary> | ||
| /// <param name="value">The input <see cref="double"/> value to test.</param> | ||
| /// <param name="target">The target <see cref="double"/> value to test for.</param> | ||
| /// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param> | ||
| /// <param name="name">The name of the input parameter being tested.</param> | ||
| /// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) > <paramref name="delta"/>.</exception> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static void IsCloseTo(double value, double target, double delta, string name) | ||
| { | ||
| if (Math.Abs(value - target) > delta) | ||
| { | ||
| ThrowHelper.ThrowArgumentExceptionForIsCloseTo(value, target, delta, name); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Asserts that the input value must not be within a given distance from a specified value. | ||
| /// </summary> | ||
| /// <param name="value">The input <see cref="double"/> value to test.</param> | ||
| /// <param name="target">The target <see cref="double"/> value to test for.</param> | ||
| /// <param name="delta">The maximum distance to allow between <paramref name="value"/> and <paramref name="target"/>.</param> | ||
| /// <param name="name">The name of the input parameter being tested.</param> | ||
| /// <exception cref="ArgumentException">Thrown if (<paramref name="value"/> - <paramref name="target"/>) <= <paramref name="delta"/>.</exception> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static void IsNotCloseTo(double value, double target, double delta, string name) | ||
| { | ||
| if (Math.Abs(value - target) <= delta) | ||
| { | ||
| ThrowHelper.ThrowArgumentExceptionForIsNotCloseTo(value, target, delta, name); | ||
| } | ||
| } | ||
| } | ||
| } | ||
74 changes: 74 additions & 0 deletions
74
Microsoft.Toolkit/Diagnostics/ThrowHelper.Comparable.Numeric.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Runtime.CompilerServices; | ||
| using Microsoft.Toolkit.Extensions; | ||
|
|
||
| #nullable enable | ||
|
|
||
| namespace Microsoft.Toolkit.Diagnostics | ||
| { | ||
| /// <summary> | ||
| /// Helper methods to throw exceptions | ||
| /// </summary> | ||
| [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1618", Justification = "Internal helper methods")] | ||
| internal static partial class ThrowHelper | ||
| { | ||
| /// <summary> | ||
| /// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(int,int,int,string)"/> fails. | ||
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static void ThrowArgumentExceptionForIsCloseTo(int value, int target, int delta, string name) | ||
| { | ||
| ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(int).ToTypeString()}) must be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs((double)((long)value - target)).ToAssertString()}"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(int,int,int,string)"/> fails. | ||
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static void ThrowArgumentExceptionForIsNotCloseTo(int value, int target, int delta, string name) | ||
| { | ||
| ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(int).ToTypeString()}) must not be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs((double)((long)value - target)).ToAssertString()}"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(float,float,float,string)"/> fails. | ||
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static void ThrowArgumentExceptionForIsCloseTo(float value, float target, float delta, string name) | ||
| { | ||
| ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(float).ToTypeString()}) must be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs(value - target).ToAssertString()}"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(float,float,float,string)"/> fails. | ||
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static void ThrowArgumentExceptionForIsNotCloseTo(float value, float target, float delta, string name) | ||
| { | ||
| ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(float).ToTypeString()}) must not be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs(value - target).ToAssertString()}"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsCloseTo(double,double,double,string)"/> fails. | ||
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static void ThrowArgumentExceptionForIsCloseTo(double value, double target, double delta, string name) | ||
| { | ||
| ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(double).ToTypeString()}) must be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs(value - target).ToAssertString()}"); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Throws an <see cref="ArgumentException"/> when <see cref="Guard.IsNotCloseTo(double,double,double,string)"/> fails. | ||
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static void ThrowArgumentExceptionForIsNotCloseTo(double value, double target, double delta, string name) | ||
| { | ||
| ThrowArgumentException(name, $"Parameter {name.ToAssertString()} ({typeof(double).ToTypeString()}) must not be within a distance of {delta.ToAssertString()} from {target.ToAssertString()}, was {value.ToAssertString()} and had a distance of {Math.Abs(value - target).ToAssertString()}"); | ||
| } | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.