├── Banner.png ├── CODE-OF-CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── SECURITY.md ├── docs ├── .gitignore ├── Docs.sln └── Jodosoft.Libraries.Docs │ ├── ContentLayout.content │ ├── Jodosoft.Libraries.Docs.shfbproj │ ├── Rename-Html-Folder.ps1 │ ├── content │ └── welcome.aml │ └── icons │ ├── Icon.png │ └── favicon.ico └── src ├── .editorconfig ├── .gitignore ├── AssemblyInfo.cs ├── Benchmarks.props ├── Directory.Build.props ├── Jodosoft.Benchmarking ├── Benchmark.cs ├── BenchmarkAttribute.cs ├── BenchmarkBuilder.cs ├── BenchmarkResult.cs ├── BenchmarkWriter.cs ├── Count.cs ├── Counter.cs ├── Jodosoft.Benchmarking.csproj └── Program.cs ├── Jodosoft.Collections.Benchmarks └── Jodosoft.Collections.Benchmarks.csproj ├── Jodosoft.Collections.Tests └── Jodosoft.Collections.Tests.csproj ├── Jodosoft.Collections ├── Array2.cs ├── DictionaryExtensions.cs ├── DictionaryLookup.cs ├── IReadOnlyArray2.cs ├── IReadOnlyLookup.cs ├── Jodosoft.Collections.csproj ├── Lookup.cs ├── LookupExtensions.cs ├── README.md ├── SortedDictionaryLookup.cs └── TAGS.md ├── Jodosoft.Geometry.Benchmarks ├── GeometryBenchmarks.cs └── Jodosoft.Geometry.Benchmarks.csproj ├── Jodosoft.Geometry.Tests ├── AARectangleNIntegralTestBase.cs ├── AARectangleNTestBase.cs ├── AARectangleNTests.cs ├── AngleNTestBase.cs ├── AngleNTests.cs ├── CircleNTestBase.cs ├── CircleNTests.cs ├── Jodosoft.Geometry.Tests.csproj ├── RectangleNTestBase.cs ├── RectangleNTests.cs ├── TriangleNTestBase.cs └── TriangleNTests.cs ├── Jodosoft.Geometry ├── AARectangleN.cs ├── AARectangleNExtensions.cs ├── AngleN.cs ├── AngleNExtensions.cs ├── CircleN.cs ├── CompatibilitySuppressions.xml ├── Jodosoft.Geometry.csproj ├── README.md ├── RectangleN.cs ├── RectangleNExtensions.cs ├── TAGS.md ├── TriangleN.cs └── VectorExtensions.cs ├── Jodosoft.Numerics.Benchmarks ├── Jodosoft.Numerics.Benchmarks.csproj ├── NumericsBenchmarks.cs └── Properties │ └── launchSettings.json ├── Jodosoft.Numerics.Tests ├── ByteMTests.cs ├── ByteNTests.cs ├── CheckedNumericConversionTestBase.cs ├── CheckedNumericTestBase.cs ├── ClampedTests.cs ├── ConvertNTests.cs ├── DecimalMTests.cs ├── DecimalNTests.cs ├── DoubleMTests.cs ├── DoubleNTests.cs ├── Fix64MTests.cs ├── Fix64Tests.cs ├── FluentAssertionsExtensions.cs ├── Int16MTests.cs ├── Int16NTests.cs ├── Int32MTests.cs ├── Int32NTests.cs ├── Int64MTests.cs ├── Int64NTests.cs ├── Jodosoft.Numerics.Tests.csproj ├── NumericBitConverterTestBase.cs ├── NumericCastTestBase.cs ├── NumericConversionConsistencyTestBase.cs ├── NumericConvertTestBase.cs ├── NumericFixedPointTestBase.cs ├── NumericFloatingPointTestBase.cs ├── NumericInfinityTestBase.cs ├── NumericIntegralTestBase.cs ├── NumericMathErrorNaNTestBase.cs ├── NumericMathTestBase.cs ├── NumericNaNTestBase.cs ├── NumericNonFloatingPointTestBase.cs ├── NumericNonInfinityTestBase.cs ├── NumericNonNaNTestBase.cs ├── NumericRandomTestBase.cs ├── NumericRealTestBase.cs ├── NumericSignedTestBase.cs ├── NumericStringConvertTestBase.cs ├── NumericTestBase.cs ├── NumericUnsignedTestBase.cs ├── NumericWrapperIntegralTestBase.cs ├── NumericWrapperTestBase.cs ├── RandomExtensions.cs ├── SByteMTests.cs ├── SByteNTests.cs ├── ScaledMathTests.cs ├── Showcase.cs ├── SingleMTests.cs ├── SingleNTests.cs ├── TestBounds.cs ├── TestUtilities.cs ├── UFix64MTests.cs ├── UFix64Tests.cs ├── UInt16MTests.cs ├── UInt16NTests.cs ├── UInt32MTests.cs ├── UInt32NTests.cs ├── UInt64MTests.cs ├── UInt64NTests.cs ├── UnitNTest.cs ├── UnitNTestBase.cs ├── Vector2NTestBase.cs ├── Vector2NTests.cs ├── Vector3NTestBase.cs └── Vector3NTests.cs ├── Jodosoft.Numerics ├── BitConverterN.cs ├── BitOperations.cs ├── ByteN.cs ├── Clamped │ ├── ByteM.cs │ ├── Clamped.cs │ ├── ConversionExtensions.cs │ ├── DecimalM.cs │ ├── DoubleM.cs │ ├── Fix64M.cs │ ├── Int16M.cs │ ├── Int32M.cs │ ├── Int64M.cs │ ├── SByteM.cs │ ├── SingleM.cs │ ├── UFix64M.cs │ ├── UInt16M.cs │ ├── UInt32M.cs │ └── UInt64M.cs ├── CompatibilitySuppressions.xml ├── Conversion.cs ├── ConvertN.cs ├── DecimalN.cs ├── DoubleN.cs ├── EnumerableExtensions.cs ├── Fix64.cs ├── Generation.cs ├── IConvert.cs ├── IConvertExtended.cs ├── IMath.cs ├── INumeric.cs ├── INumericBitConverter.cs ├── INumericExtended.cs ├── INumericRandom.cs ├── INumericStatic.cs ├── Int16N.cs ├── Int32N.cs ├── Int64N.cs ├── Jodosoft.Numerics.csproj ├── MathN.cs ├── Numeric.cs ├── NumericExtensions.cs ├── README.md ├── RandomExtensions.cs ├── SByteN.cs ├── Scaled.cs ├── SingleN.cs ├── TAGS.md ├── UFix64.cs ├── UInt16N.cs ├── UInt32N.cs ├── UInt64N.cs ├── UnitN.cs ├── Vector2N.cs ├── Vector3N.cs └── VectorExtensions.cs ├── Jodosoft.Primitives.Benchmarks └── Jodosoft.Primitives.Benchmarks.csproj ├── Jodosoft.Primitives.Tests ├── BinaryIOTestBase.cs ├── DynamicInvokeTests.cs ├── FuncExtensionsTests.cs ├── Jodosoft.Primitives.Tests.csproj └── RandomExtensionsTests.cs ├── Jodosoft.Primitives ├── BinaryConvert.cs ├── BinaryReaderExtensions.cs ├── BinaryWriterExtensions.cs ├── BitOperations.cs ├── Compatibility │ ├── BitConverterShim.cs │ ├── DoubleShim.cs │ ├── HashCodeShim.cs │ ├── MathFShim.cs │ ├── MathShim.cs │ ├── SingleShim.cs │ └── ValueTupleShim.cs ├── ConvertibleExtensions.cs ├── DefaultProvider.cs ├── DynamicInvoke.cs ├── FuncExtensions.cs ├── IBinaryIO.cs ├── IProvider.cs ├── IVariantRandom.cs ├── Jodosoft.Primitives.csproj ├── README.md ├── RandomExtensions.cs ├── StringUtilities.cs ├── TAGS.md └── Variants.cs ├── Jodosoft.Testing.NewtonsoftJson ├── Jodosoft.Testing.NewtonsoftJson.csproj └── JsonConvertTestBase.cs ├── Jodosoft.Testing.Tests ├── AssertSameTests.cs └── Jodosoft.Testing.Tests.csproj ├── Jodosoft.Testing ├── AssertSame.cs ├── AssertionMethodAttribute.cs ├── FixtureExtensions.cs ├── FormattableTestBase.cs ├── GlobalFixtureBase.cs ├── Jodosoft.Testing.csproj ├── ObjectTestBase.cs ├── SerializableTestBase.cs └── TestLocal.cs ├── Libraries.sln ├── PackageIcon.png ├── Packages.props ├── PackagesNonBreaking.props ├── TestAssemblyInfo.cs └── Tests.props /Banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jodosoft/Libraries/7c1e73eacaace8374bd8e6b99f50817da22708ba/Banner.png -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ==== 3 | 4 | Contributions are welcome at https://github.com/Jodosoft/Libraries (the home of this repository). Contributors are requested to adhere to the [code of conduct](CODE-OF-CONDUCT.md). 5 | 6 | Please consult the [.NET Runtime guide](https://github.com/dotnet/runtime/blob/main/CONTRIBUTING.md) for a good model of how to contribute. 7 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Joe Lawry-Short 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Vulnerabilities should be reported privately to support@jodosoft.com. 4 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | .vs/ -------------------------------------------------------------------------------- /docs/Docs.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32519.379 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{7CF6DF6D-3B04-46F8-A40B-537D21BCA0B4}") = "Jodosoft.Libraries.Docs", "Jodosoft.Libraries.Docs\Jodosoft.Libraries.Docs.shfbproj", "{22A055ED-ABAB-4BDD-8989-6EB738411445}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D824DA2D-77E1-46FB-8E51-D49AE7A7B9D8}" 9 | ProjectSection(SolutionItems) = preProject 10 | .gitignore = .gitignore 11 | CNAME = CNAME 12 | EndProjectSection 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {22A055ED-ABAB-4BDD-8989-6EB738411445}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {22A055ED-ABAB-4BDD-8989-6EB738411445}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {22A055ED-ABAB-4BDD-8989-6EB738411445}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {22A055ED-ABAB-4BDD-8989-6EB738411445}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {0F607B33-F092-419F-82D9-C7D2879B3ED8} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /docs/Jodosoft.Libraries.Docs/ContentLayout.content: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/Jodosoft.Libraries.Docs/Rename-Html-Folder.ps1: -------------------------------------------------------------------------------- 1 | ((Get-Content -path .\bin\docs\index.html -Raw) -replace 'html/','api/') | Set-Content -Path .\bin\docs\index.html 2 | ((Get-Content -path .\bin\docs\PageNotFound.html -Raw) -replace 'html/','api/') | Set-Content -Path .\bin\docs\PageNotFound.html 3 | ((Get-Content -path .\bin\docs\search.html -Raw) -replace 'html/','api/') | Set-Content -Path .\bin\docs\search.html 4 | ((Get-Content -path .\bin\docs\fti\FTI_Files.json -Raw) -replace 'html/','api/') | Set-Content -Path .\bin\docs\fti\FTI_Files.json 5 | Rename-Item -Path .\bin\docs\html -NewName "api" -------------------------------------------------------------------------------- /docs/Jodosoft.Libraries.Docs/content/welcome.aml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Simple, reliable .NET libraries covering numbers, geometry and data structures. 6 | 7 | 8 |
9 | Getting started 10 | 11 | 12 | For a general information, see the repository page on GitHub at 13 | https://github.com/Jodosoft/Libraries/ 14 | https://github.com/Jodosoft/Libraries/ 15 | . 16 | 17 | 18 | For API reference documentation, use the the table of contents to navigate each namespace. 19 | 20 | 21 |
22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /docs/Jodosoft.Libraries.Docs/icons/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jodosoft/Libraries/7c1e73eacaace8374bd8e6b99f50817da22708ba/docs/Jodosoft.Libraries.Docs/icons/Icon.png -------------------------------------------------------------------------------- /docs/Jodosoft.Libraries.Docs/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jodosoft/Libraries/7c1e73eacaace8374bd8e6b99f50817da22708ba/docs/Jodosoft.Libraries.Docs/icons/favicon.ico -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | .vs/ 4 | *opencover.xml 5 | *coverage.xml 6 | *cobertura.xml 7 | *.trx 8 | TestResults/ 9 | output/ 10 | publish/ -------------------------------------------------------------------------------- /src/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Diagnostics.CodeAnalysis; 22 | using System.Runtime.CompilerServices; 23 | 24 | [assembly: InternalsVisibleTo("Jodosoft.Benchmarking.Tests")] 25 | [assembly: InternalsVisibleTo("Jodosoft.Geometry.Benchmarks")] 26 | [assembly: InternalsVisibleTo("Jodosoft.Geometry.Tests")] 27 | [assembly: InternalsVisibleTo("Jodosoft.Collections.Benchmarks")] 28 | [assembly: InternalsVisibleTo("Jodosoft.Collections.Tests")] 29 | [assembly: InternalsVisibleTo("Jodosoft.Numerics.Benchmarks")] 30 | [assembly: InternalsVisibleTo("Jodosoft.Numerics.Tests")] 31 | [assembly: InternalsVisibleTo("Jodosoft.Testing.Tests")] 32 | 33 | [assembly: SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", MessageId = "csharpsquid", Justification = "False positive on csharpsquid suppressions")] 34 | 35 | [assembly: CLSCompliant(true)] 36 | -------------------------------------------------------------------------------- /src/Benchmarks.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net5.0 4 | Exe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | false 5 | true 6 | latest 7 | true 8 | 4 9 | true 10 | 11 | 12 | 13 | HAS_VALUE_TUPLES;HAS_SPANS;HAS_DEFAULT_INTERFACE_METHODS;$(AdditionalConstants) 14 | 15 | 16 | 17 | HAS_VALUE_TUPLES;HAS_SPANS;HAS_DEFAULT_INTERFACE_METHODS;$(AdditionalConstants) 18 | 19 | 20 | 21 | HAS_VALUE_TUPLES;HAS_SPANS;HAS_DEFAULT_INTERFACE_METHODS;$(AdditionalConstants) 22 | 23 | 24 | 25 | HAS_VALUE_TUPLES;HAS_SPANS;HAS_DEFAULT_INTERFACE_METHODS;$(AdditionalConstants) 26 | 27 | 28 | 29 | HAS_VALUE_TUPLES;$(AdditionalConstants) 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/Jodosoft.Benchmarking/Benchmark.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Diagnostics; 22 | 23 | namespace Jodosoft.Benchmarking 24 | { 25 | public class Benchmark : Benchmark 26 | { 27 | public Func DataFactory { get; } 28 | public Func Subject1 { get; } 29 | public Func Subject2 { get; } 30 | 31 | public Benchmark(string name, Func dataFactory, Func subject1, Func subject2) : base(name) 32 | { 33 | DataFactory = dataFactory ?? throw new ArgumentNullException(nameof(dataFactory)); 34 | Subject2 = subject2 ?? throw new ArgumentNullException(nameof(subject2)); 35 | Subject1 = subject1 ?? throw new ArgumentNullException(nameof(subject1)); 36 | } 37 | 38 | public override BenchmarkResult Execute(TimeSpan duration) 39 | { 40 | (Count Subject1, Count Subject2) measurements = Counter.Measure(DataFactory, Subject1, Subject2, duration); 41 | 42 | return new BenchmarkResult(Name, measurements.Subject1, measurements.Subject2); 43 | } 44 | } 45 | 46 | public abstract class Benchmark 47 | { 48 | public string Name { get; } 49 | 50 | protected Benchmark(string name) 51 | { 52 | Name = name ?? throw new ArgumentNullException(nameof(name)); 53 | } 54 | 55 | public abstract BenchmarkResult Execute(TimeSpan duration); 56 | 57 | public static BenchmarkBuilder.WithNameAndData Using(Func factory) 58 | { 59 | return new BenchmarkBuilder.WithNameAndData(new StackTrace().GetFrame(1).GetMethod().Name, factory); 60 | } 61 | 62 | public static BenchmarkBuilder.WithNameAndData UsingData(T value) 63 | { 64 | return new BenchmarkBuilder.WithNameAndData(new StackTrace().GetFrame(1).GetMethod().Name, () => value); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Jodosoft.Benchmarking/BenchmarkAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Diagnostics.CodeAnalysis; 22 | 23 | namespace Jodosoft.Benchmarking 24 | { 25 | [ExcludeFromCodeCoverage] 26 | [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] 27 | public sealed class BenchmarkAttribute : Attribute 28 | { 29 | public string Name { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Jodosoft.Benchmarking/BenchmarkBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Benchmarking 23 | { 24 | public static class BenchmarkBuilder 25 | { 26 | public sealed class WithNameAndData 27 | { 28 | public string Name { get; } 29 | public Func DataFactory { get; } 30 | 31 | public WithNameAndData(string name, Func dataFactory) 32 | { 33 | Name = name ?? throw new ArgumentNullException(nameof(name)); 34 | DataFactory = dataFactory ?? throw new ArgumentNullException(nameof(dataFactory)); 35 | } 36 | 37 | public WithNameDataAndSubject1 Measure(Func subject1) 38 | { 39 | return new WithNameDataAndSubject1(Name, DataFactory, subject1); 40 | } 41 | } 42 | 43 | public class WithNameDataAndSubject1 44 | { 45 | public string Name { get; } 46 | public Func DataFactory { get; } 47 | public Func Subject1 { get; } 48 | 49 | public WithNameDataAndSubject1(string name, Func dataFactory, Func subject1) 50 | { 51 | Name = name ?? throw new ArgumentNullException(nameof(name)); 52 | DataFactory = dataFactory ?? throw new ArgumentNullException(nameof(dataFactory)); 53 | Subject1 = subject1 ?? throw new ArgumentNullException(nameof(subject1)); 54 | } 55 | 56 | public Benchmark Versus(Func subject2) 57 | { 58 | return new Benchmark(Name, DataFactory, Subject1, subject2); 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Jodosoft.Benchmarking/BenchmarkResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace Jodosoft.Benchmarking 24 | { 25 | public sealed class BenchmarkResult : IEquatable 26 | { 27 | public string Name { get; } 28 | public Count Subject1 { get; } 29 | public Count Subject2 { get; } 30 | 31 | public BenchmarkResult(string name, Count subject1, Count subject2) 32 | { 33 | if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Must not be null, empty or whitespace.", nameof(name)); 34 | Name = name; 35 | Subject1 = subject1; 36 | Subject2 = subject2; 37 | } 38 | 39 | public override bool Equals(object obj) => Equals(obj as BenchmarkResult); 40 | public bool Equals(BenchmarkResult other) => other != null && Name == other.Name && Subject2.Equals(other.Subject2) && Subject1.Equals(other.Subject1); 41 | public override int GetHashCode() => HashCode.Combine(Name, Subject2, Subject1); 42 | 43 | public static bool operator ==(BenchmarkResult left, BenchmarkResult right) => EqualityComparer.Default.Equals(left, right); 44 | public static bool operator !=(BenchmarkResult left, BenchmarkResult right) => !(left == right); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Jodosoft.Benchmarking/Count.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Diagnostics.CodeAnalysis; 22 | 23 | namespace Jodosoft.Benchmarking 24 | { 25 | [ExcludeFromCodeCoverage] 26 | public sealed class Count : IEquatable 27 | { 28 | public long Executions { get; } 29 | public TimeSpan TotalTime { get; } 30 | 31 | public Count(long executions, TimeSpan totalTime) 32 | { 33 | if (executions <= 0) throw new ArgumentOutOfRangeException(nameof(executions), executions, "Must be positive."); 34 | if (totalTime <= TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(totalTime), totalTime, "Must be positive."); 35 | 36 | Executions = executions; 37 | TotalTime = totalTime; 38 | } 39 | 40 | public TimeSpan GetAverageTime() => new TimeSpan(TotalTime.Ticks / Executions); 41 | 42 | public double GetExecutionsPerSecond() => Executions / TotalTime.TotalSeconds; 43 | 44 | public override bool Equals(object obj) => Equals(obj as Count); 45 | 46 | public bool Equals(Count other) => other != null && Executions == other.Executions && TotalTime.Equals(other.TotalTime); 47 | 48 | public override int GetHashCode() => HashCode.Combine(Executions, TotalTime); 49 | 50 | public static bool operator ==(Count left, Count right) => left.Equals(right); 51 | 52 | public static bool operator !=(Count left, Count right) => !(left == right); 53 | 54 | public static Count operator +(Count count1, Count count2) 55 | => new Count(count1.Executions + count2.Executions, count1.TotalTime + count2.TotalTime); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Jodosoft.Benchmarking/Counter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Diagnostics; 22 | using System.Diagnostics.CodeAnalysis; 23 | using System.Runtime.CompilerServices; 24 | 25 | namespace Jodosoft.Benchmarking 26 | { 27 | [ExcludeFromCodeCoverage] 28 | public static class Counter 29 | { 30 | private static readonly TimeSpan TrialDuration = TimeSpan.FromSeconds(1); 31 | 32 | public static (Count Subject1, Count Subject2) Measure( 33 | Func inputFactory, 34 | Func subject1, 35 | Func subject2, 36 | TimeSpan overallDuration) 37 | { 38 | Stopwatch overallStopwatch = Stopwatch.StartNew(); 39 | 40 | T input = inputFactory(); 41 | Count count1 = Measure(subject1, input, TrialDuration); 42 | Count count2 = Measure(subject2, input, TrialDuration); 43 | 44 | while (overallStopwatch.Elapsed < overallDuration) 45 | { 46 | input = inputFactory(); 47 | count1 = Add(count1, Measure(subject1, input, TrialDuration)); 48 | count2 = Add(count2, Measure(subject2, input, TrialDuration)); 49 | } 50 | 51 | return (count1, count2); 52 | } 53 | 54 | [MethodImpl(MethodImplOptions.NoOptimization)] 55 | public static Count Measure(Func subject, T input, TimeSpan duration) 56 | { 57 | object checkObj = new object(); 58 | Stopwatch stopwatch = new Stopwatch(); 59 | double maxTicks = duration.TotalSeconds * Stopwatch.Frequency; 60 | long iterations = 0; 61 | object obj; 62 | stopwatch.Start(); 63 | do 64 | { 65 | obj = subject(input); 66 | iterations++; 67 | } while (stopwatch.ElapsedTicks < maxTicks); 68 | stopwatch.Stop(); 69 | if (ReferenceEquals(obj, checkObj)) throw new InvalidOperationException(); 70 | return new Count(iterations, stopwatch.Elapsed); 71 | } 72 | 73 | private static Count Add(Count measurement1, Count measurement2) 74 | { 75 | return new Count(measurement1.Executions + measurement2.Executions, measurement1.TotalTime + measurement2.TotalTime); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Jodosoft.Benchmarking/Jodosoft.Benchmarking.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net5.0 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections.Benchmarks/Jodosoft.Collections.Benchmarks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections.Tests/Jodosoft.Collections.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/Array2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Collections 23 | { 24 | public static class Array2 25 | { 26 | public static Array2 Empty() => Array2.Empty; 27 | } 28 | 29 | public sealed class Array2 : IReadOnlyArray2 30 | { 31 | public static readonly Array2 Empty = new Array2(0, 0); 32 | 33 | private readonly T[] _array; 34 | 35 | public int Length => _array.Length; 36 | public int LengthX { get; } 37 | public int LengthY { get; } 38 | 39 | public T this[int x, int y] 40 | { 41 | get => _array[(y * LengthX) + x]; 42 | set => _array[(y * LengthX) + x] = value; 43 | } 44 | 45 | public Array2(int lengthX, int lengthY) 46 | { 47 | _array = new T[lengthX * lengthY]; 48 | LengthX = lengthX; 49 | LengthY = lengthY; 50 | } 51 | 52 | #if HAS_SPANS 53 | public ReadOnlySpan AsSpan() => _array.AsSpan(); 54 | public ReadOnlyMemory AsMemory() => _array.AsMemory(); 55 | #endif 56 | 57 | public T[] ToArray() 58 | { 59 | T[]? copy = new T[_array.Length]; 60 | Array.Copy(_array, copy, _array.Length); 61 | return copy; 62 | } 63 | 64 | public override bool Equals(object? obj) => _array.Equals(obj); 65 | public override int GetHashCode() => _array.GetHashCode(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/DictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Collections.Generic; 21 | 22 | namespace Jodosoft.Collections 23 | { 24 | public static class DictionaryExtensions 25 | { 26 | public static DictionaryLookup ToLookup(this Dictionary dictionary) where TKey : notnull 27 | => new DictionaryLookup(dictionary); 28 | 29 | public static SortedDictionaryLookup ToLookup(this SortedDictionary dictionary) where TKey : notnull 30 | => new SortedDictionaryLookup(dictionary); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/DictionaryLookup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Collections.Generic; 21 | 22 | namespace Jodosoft.Collections 23 | { 24 | public sealed class DictionaryLookup : IReadOnlyLookup where TKey : notnull 25 | { 26 | private readonly Dictionary _dictionary; 27 | 28 | public DictionaryLookup(Dictionary dictionary) 29 | { 30 | _dictionary = dictionary; 31 | } 32 | 33 | public TValue this[TKey key] => _dictionary[key]; 34 | public IReadOnlyCollection Keys => _dictionary.Keys; 35 | public IReadOnlyCollection Values => _dictionary.Values; 36 | public bool ContainsKey(TKey key) => _dictionary.ContainsKey(key); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/IReadOnlyArray2.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | namespace Jodosoft.Collections 21 | { 22 | public interface IReadOnlyArray2 23 | { 24 | T this[int x, int y] { get; } 25 | 26 | int Length { get; } 27 | int LengthX { get; } 28 | int LengthY { get; } 29 | 30 | T[] ToArray(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/IReadOnlyLookup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Collections.Generic; 21 | 22 | namespace Jodosoft.Collections 23 | { 24 | public interface IReadOnlyLookup 25 | { 26 | TValue this[TKey key] { get; } 27 | IReadOnlyCollection Keys { get; } 28 | IReadOnlyCollection Values { get; } 29 | bool ContainsKey(TKey key); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/Jodosoft.Collections.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/Lookup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Collections.Generic; 21 | 22 | namespace Jodosoft.Collections 23 | { 24 | public static class Lookup 25 | { 26 | public static IReadOnlyLookup Empty() where TKey : notnull 27 | => new Dictionary(0).ToLookup(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/LookupExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | 24 | namespace Jodosoft.Collections 25 | { 26 | public static class LookupExtensions 27 | { 28 | public static bool TryGetValue(this IReadOnlyLookup instance, TKey key, out TValue value) 29 | { 30 | if (instance.ContainsKey(key)) 31 | { 32 | value = instance[key]; 33 | return true; 34 | } 35 | value = (new TValue[1])[0]; 36 | return false; 37 | } 38 | 39 | public static IReadOnlyLookup ToReadOnlyLookup(this IReadOnlyDictionary dictionary) where TKey : notnull 40 | => new DictionaryLookup(dictionary.ToDictionary(x => x.Key, x => x.Value)); 41 | 42 | public static IReadOnlyLookup ToReadOnlyLookup(this IEnumerable source, Func keySelector) where TKey : notnull 43 | => new DictionaryLookup(source.ToDictionary(keySelector)); 44 | 45 | public static IReadOnlyLookup ToReadOnlyLookup(this IEnumerable source, Func keySelector, Func elementSelector) where TKey : notnull 46 | => new DictionaryLookup(source.ToDictionary(keySelector, elementSelector)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/README.md: -------------------------------------------------------------------------------- 1 | Extended collection classes, utilities and abstractions. 2 | 3 | See: https://github.com/Jodosoft/Libraries/#collections -------------------------------------------------------------------------------- /src/Jodosoft.Collections/SortedDictionaryLookup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | namespace Jodosoft.Collections 24 | { 25 | public sealed class SortedDictionaryLookup : IReadOnlyLookup where TKey : notnull 26 | { 27 | private readonly SortedDictionary _dictionary; 28 | 29 | public SortedDictionaryLookup(SortedDictionary dictionary) 30 | { 31 | _dictionary = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); 32 | } 33 | 34 | public TValue this[TKey key] => _dictionary[key]; 35 | public IReadOnlyCollection Keys => _dictionary.Keys; 36 | public IReadOnlyCollection Values => _dictionary.Values; 37 | public bool ContainsKey(TKey key) => _dictionary.ContainsKey(key); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Jodosoft.Collections/TAGS.md: -------------------------------------------------------------------------------- 1 | collection, collections, generic, jodo, jodosoft -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Benchmarks/GeometryBenchmarks.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Diagnostics.CodeAnalysis; 22 | using Jodosoft.Benchmarking; 23 | using Jodosoft.Numerics; 24 | using Jodosoft.Primitives; 25 | 26 | namespace Jodosoft.Geometry.Benchmarks 27 | { 28 | [ExcludeFromCodeCoverage] 29 | public static class GeometryBenchmarks 30 | { 31 | private static readonly Random Random = new Random(); 32 | 33 | [Benchmark] 34 | public static Benchmark AARectangleNGetArea_Versus_SingleMultiplication() 35 | { 36 | return Benchmark 37 | .Using(() => 38 | { 39 | float singleWidth = Random.NextSingle(Variants.LowMagnitude); 40 | float singleHeight = Random.NextSingle(Variants.LowMagnitude); 41 | AARectangleN aaRectangle = new AARectangleN( 42 | Random.NextSingle(Variants.LowMagnitude), Random.NextSingle(Variants.LowMagnitude), singleWidth, singleHeight); 43 | return (singleWidth, singleHeight, aaRectangle); 44 | }) 45 | .Measure(x => x.aaRectangle.GetArea()) 46 | .Versus(x => x.singleWidth * x.singleHeight); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Benchmarks/Jodosoft.Geometry.Benchmarks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Tests/AARectangleNIntegralTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using FluentAssertions; 21 | using Jodosoft.Numerics; 22 | using Jodosoft.Testing; 23 | using NUnit.Framework; 24 | 25 | namespace Jodosoft.Geometry.Tests 26 | { 27 | public abstract class AARectangleNIntegralTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 28 | { 29 | [SetUp] 30 | public void SetUp() => Assert.That(Numeric.IsIntegral()); 31 | 32 | [Test, Repeat(RandomVariations)] 33 | public void FromBottomLeft_UnitSquare_CorrectVertices() 34 | { 35 | //arrange 36 | AARectangleN subject = AARectangleN.FromBottomLeft( 37 | new Vector2N(Numeric.Zero(), Numeric.Zero()), 38 | new Vector2N(Numeric.One(), Numeric.One())); 39 | 40 | //act 41 | Vector2N bottomLeftResult = subject.GetBottomLeft(); 42 | Vector2N topRightResult = subject.GetTopRight(); 43 | 44 | //assert 45 | bottomLeftResult.Should().Be(new Vector2N(Numeric.Zero(), Numeric.Zero())); 46 | topRightResult.Should().Be(new Vector2N(Numeric.One(), Numeric.One())); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Tests/AARectangleNTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Numerics; 21 | using Jodosoft.Primitives.Tests; 22 | using Jodosoft.Testing; 23 | 24 | namespace Jodosoft.Geometry.Tests 25 | { 26 | public static class AARectangleNTests 27 | { 28 | public sealed class AARectangleIntegralFixedPointTests : AARectangleNTestBase { } 29 | public sealed class AARectangleIntegralFloatingPointTests : AARectangleNTestBase { } 30 | public sealed class AARectangleIntegralUnsignedIntegralTests : AARectangleNIntegralTestBase { } 31 | public sealed class FixedPointBinaryIOTests : BinaryIOTestBase> { } 32 | public sealed class FixedPointFormattableTests : FormattableTestBase> { } 33 | public sealed class FixedPointObjectTests : ObjectTestBase> { } 34 | public sealed class FixedPointSerializableTests : SerializableTestBase> { } 35 | public sealed class FloatingPointBinaryIOTests : BinaryIOTestBase> { } 36 | public sealed class FloatingPointFormattableTests : FormattableTestBase> { } 37 | public sealed class FloatingPointObjectTests : ObjectTestBase> { } 38 | public sealed class FloatingPointSerializableTests : SerializableTestBase> { } 39 | public sealed class UnsignedIntegralBinaryIOTests : BinaryIOTestBase> { } 40 | public sealed class UnsignedIntegralFormattableTests : FormattableTestBase> { } 41 | public sealed class UnsignedIntegralObjectTests : ObjectTestBase> { } 42 | public sealed class UnsignedIntegralSerializableTests : SerializableTestBase> { } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Tests/AngleNTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Numerics; 21 | using Jodosoft.Primitives.Tests; 22 | using Jodosoft.Testing; 23 | 24 | namespace Jodosoft.Geometry.Tests 25 | { 26 | public static class AngleNTests 27 | { 28 | public sealed class FixedPointBinaryIOTests : BinaryIOTestBase> { } 29 | public sealed class FixedPointFormattableTests : FormattableTestBase> { } 30 | public sealed class FixedPointGeneralTests : AngleNTestBase { } 31 | public sealed class FixedPointObjectTests : ObjectTestBase> { } 32 | public sealed class FixedPointSerializableFixedPointTests : SerializableTestBase> { } 33 | public sealed class FloatingPointBinaryIOTests : BinaryIOTestBase> { } 34 | public sealed class FloatingPointFormattableTests : FormattableTestBase> { } 35 | public sealed class FloatingPointGeneralTests : AngleNTestBase { } 36 | public sealed class FloatingPointObjectTests : ObjectTestBase> { } 37 | public sealed class FloatingPointSerializableTests : SerializableTestBase> { } 38 | public sealed class UnsignedIntegralBinaryIOTests : BinaryIOTestBase> { } 39 | public sealed class UnsignedIntegralFormattableTests : FormattableTestBase> { } 40 | public sealed class UnsignedIntegralGeneralTests : AngleNTestBase { } 41 | public sealed class UnsignedIntegralObjectTests : ObjectTestBase> { } 42 | public sealed class UnsignedIntegralSerializableTests : SerializableTestBase> { } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Tests/CircleNTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Numerics; 21 | using Jodosoft.Primitives.Tests; 22 | using Jodosoft.Testing; 23 | 24 | namespace Jodosoft.Geometry.Tests 25 | { 26 | public static class CircleNTests 27 | { 28 | public sealed class FixedPointBinaryIOTests : BinaryIOTestBase> { } 29 | public sealed class FixedPointFormattableTests : FormattableTestBase> { } 30 | public sealed class FixedPointGeneralTests : CircleNTestBase { } 31 | public sealed class FixedPointObjectTests : ObjectTestBase> { } 32 | public sealed class FixedPointSerializableTests : SerializableTestBase> { } 33 | public sealed class FloatingPointBinaryIOTests : BinaryIOTestBase> { } 34 | public sealed class FloatingPointFormattableTests : FormattableTestBase> { } 35 | public sealed class FloatingPointGeneralTests : CircleNTestBase { } 36 | public sealed class FloatingPointObjectTests : ObjectTestBase> { } 37 | public sealed class FloatingPointSerializableTests : SerializableTestBase> { } 38 | public sealed class UnsignedIntegralBinaryIOTests : BinaryIOTestBase> { } 39 | public sealed class UnsignedIntegralFormattableTests : FormattableTestBase> { } 40 | public sealed class UnsignedIntegralGeneralTests : CircleNTestBase { } 41 | public sealed class UnsignedIntegralObjectTests : ObjectTestBase> { } 42 | public sealed class UnsignedIntegralSerializableTests : SerializableTestBase> { } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Tests/Jodosoft.Geometry.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Tests/RectangleNTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Numerics; 21 | using Jodosoft.Primitives.Tests; 22 | using Jodosoft.Testing; 23 | 24 | namespace Jodosoft.Geometry.Tests 25 | { 26 | public static class RectangleNTests 27 | { 28 | public sealed class FixedPointBinaryIOTests : BinaryIOTestBase> { } 29 | public sealed class FixedPointFormattableTests : FormattableTestBase> { } 30 | public sealed class FixedPointObjectTests : ObjectTestBase> { } 31 | public sealed class FixedPointRectangleTests : RectangleNTestBase { } 32 | public sealed class FixedPointSerializableTests : SerializableTestBase> { } 33 | public sealed class FloatingPointBinaryIOTests : BinaryIOTestBase> { } 34 | public sealed class FloatingPointFormattableTests : FormattableTestBase> { } 35 | public sealed class FloatingPointObjectTests : ObjectTestBase> { } 36 | public sealed class FloatingPointRectangleTests : RectangleNTestBase { } 37 | public sealed class FloatingPointSerializableTests : SerializableTestBase> { } 38 | public sealed class UnsignedIntegralBinaryIOTests : BinaryIOTestBase> { } 39 | public sealed class UnsignedIntegralFormattableTests : FormattableTestBase> { } 40 | public sealed class UnsignedIntegralObjectTests : ObjectTestBase> { } 41 | public sealed class UnsignedIntegralRectangleTests : RectangleNTestBase { } 42 | public sealed class UnsignedIntegralSerializableTests : SerializableTestBase> { } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Tests/TriangleNTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Diagnostics.CodeAnalysis; 21 | using Jodosoft.Numerics; 22 | using Jodosoft.Primitives; 23 | using Jodosoft.Testing; 24 | using NUnit.Framework; 25 | 26 | namespace Jodosoft.Geometry.Tests 27 | { 28 | 29 | [SuppressMessage("csharpsquid", "S1940:Boolean checks should not be inverted.", Justification = "Intentional for verifying operator consistency.")] 30 | public abstract class TriangleNTestBase 31 | : GlobalFixtureBase where TNumeric : struct, INumeric 32 | { 33 | [Test, Repeat(RandomVariations)] 34 | public void EqualsMethods_RandomValues_SameOutcome() 35 | { 36 | //arrange 37 | TriangleN input1 = Random.NextVariant>(); 38 | TriangleN input2 = Random.Choose(input1, Random.NextVariant>()); 39 | 40 | //act 41 | //assert 42 | AssertSame.Outcome( 43 | () => input1.Equals(input2), 44 | () => input1.Equals((object)input2), 45 | () => input1 == input2, 46 | () => !(input1 != input2)); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry.Tests/TriangleNTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Numerics; 21 | using Jodosoft.Primitives.Tests; 22 | using Jodosoft.Testing; 23 | 24 | namespace Jodosoft.Geometry.Tests 25 | { 26 | public static class TriangleNTests 27 | { 28 | public sealed class FixedPointBinaryIOTests : BinaryIOTestBase> { } 29 | public sealed class FixedPointFormattableTests : FormattableTestBase> { } 30 | public sealed class FixedPointGeneralTests : TriangleNTestBase { } 31 | public sealed class FixedPointObjectTests : ObjectTestBase> { } 32 | public sealed class FixedPointSerializableTests : SerializableTestBase> { } 33 | public sealed class FloatingPointBinaryIOTests : BinaryIOTestBase> { } 34 | public sealed class FloatingPointFormattableTests : FormattableTestBase> { } 35 | public sealed class FloatingPointGeneralTests : TriangleNTestBase { } 36 | public sealed class FloatingPointObjectTests : ObjectTestBase> { } 37 | public sealed class FloatingPointSerializableTests : SerializableTestBase> { } 38 | public sealed class UnsignedIntegralBinaryIOTests : BinaryIOTestBase> { } 39 | public sealed class UnsignedIntegralFormattableTests : FormattableTestBase> { } 40 | public sealed class UnsignedIntegralGeneralTests : TriangleNTestBase { } 41 | public sealed class UnsignedIntegralObjectTests : ObjectTestBase> { } 42 | public sealed class UnsignedIntegralSerializableTests : SerializableTestBase> { } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry/AngleNExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Numerics; 21 | 22 | namespace Jodosoft.Geometry 23 | { 24 | public static class AngleNExtensions 25 | { 26 | public static TNumeric GetRadians(this AngleN angle) where TNumeric : struct, INumeric 27 | => AngleN.DegreesToRadians(angle.Degrees); 28 | 29 | public static TNumeric Cos(this AngleN angle) where TNumeric : struct, INumeric 30 | => MathN.Cos(angle.GetRadians()); 31 | 32 | public static TNumeric Cosh(this AngleN angle) where TNumeric : struct, INumeric 33 | => MathN.Cosh(angle.GetRadians()); 34 | 35 | public static TNumeric Sin(this AngleN angle) where TNumeric : struct, INumeric 36 | => MathN.Sin(angle.GetRadians()); 37 | 38 | public static TNumeric Sinh(this AngleN angle) where TNumeric : struct, INumeric 39 | => MathN.Sinh(angle.GetRadians()); 40 | 41 | public static TNumeric Tan(this AngleN angle) where TNumeric : struct, INumeric 42 | => MathN.Tan(angle.GetRadians()); 43 | 44 | public static TNumeric Tanh(this AngleN angle) where TNumeric : struct, INumeric 45 | => MathN.Tanh(angle.GetRadians()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry/CompatibilitySuppressions.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | CP0002 5 | M:Jodosoft.Geometry.AARectangleN`1.op_Implicit(Jodosoft.Geometry.AARectangleN{`0})~System.ValueTuple{`0,`0,`0,`0} 6 | lib/netstandard2.0/Jodosoft.Geometry.dll 7 | lib/net461/Jodosoft.Geometry.dll 8 | 9 | 10 | CP0002 11 | M:Jodosoft.Geometry.AARectangleN`1.op_Implicit(Jodosoft.Geometry.AARectangleN{`0})~System.ValueTuple{Jodosoft.Numerics.Vector2N{`0},Jodosoft.Numerics.Vector2N{`0}} 12 | lib/netstandard2.0/Jodosoft.Geometry.dll 13 | lib/net461/Jodosoft.Geometry.dll 14 | 15 | 16 | CP0002 17 | M:Jodosoft.Geometry.AARectangleN`1.op_Implicit(System.ValueTuple{`0,`0,`0,`0})~Jodosoft.Geometry.AARectangleN{`0} 18 | lib/netstandard2.0/Jodosoft.Geometry.dll 19 | lib/net461/Jodosoft.Geometry.dll 20 | 21 | 22 | CP0002 23 | M:Jodosoft.Geometry.AARectangleN`1.op_Implicit(System.ValueTuple{Jodosoft.Numerics.Vector2N{`0},Jodosoft.Numerics.Vector2N{`0}})~Jodosoft.Geometry.AARectangleN{`0} 24 | lib/netstandard2.0/Jodosoft.Geometry.dll 25 | lib/net461/Jodosoft.Geometry.dll 26 | 27 | 28 | CP0002 29 | M:Jodosoft.Geometry.TriangleN`1.op_Implicit(Jodosoft.Geometry.TriangleN{`0})~System.ValueTuple{Jodosoft.Numerics.Vector2N{`0},Jodosoft.Numerics.Vector2N{`0},Jodosoft.Numerics.Vector2N{`0}} 30 | lib/netstandard2.0/Jodosoft.Geometry.dll 31 | lib/net461/Jodosoft.Geometry.dll 32 | 33 | 34 | CP0002 35 | M:Jodosoft.Geometry.TriangleN`1.op_Implicit(System.ValueTuple{Jodosoft.Numerics.Vector2N{`0},Jodosoft.Numerics.Vector2N{`0},Jodosoft.Numerics.Vector2N{`0}})~Jodosoft.Geometry.TriangleN{`0} 36 | lib/netstandard2.0/Jodosoft.Geometry.dll 37 | lib/net461/Jodosoft.Geometry.dll 38 | 39 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry/Jodosoft.Geometry.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Jodosoft.Geometry/README.md: -------------------------------------------------------------------------------- 1 | Geometric structures and utilities that support generic number types. 2 | 3 | See: https://github.com/Jodosoft/Libraries/#geometry -------------------------------------------------------------------------------- /src/Jodosoft.Geometry/TAGS.md: -------------------------------------------------------------------------------- 1 | geometry, geometric, angle, angles, shape, shapes, 2d, jodo, jodosoft -------------------------------------------------------------------------------- /src/Jodosoft.Geometry/VectorExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Numerics; 21 | 22 | namespace Jodosoft.Geometry 23 | { 24 | public static class VectorExtensions 25 | { 26 | public static Vector2N RotateAround(this Vector2N vector, Vector2N pivot, AngleN angle) where TNumeric : struct, INumeric 27 | { 28 | if (angle == AngleN.Zero()) return vector; 29 | 30 | AngleN newAngle = -angle; 31 | Vector2N difference = vector - pivot; 32 | return pivot + new Vector2N( 33 | difference.X.Multiply(newAngle.Cos()).Subtract(difference.Y.Multiply(newAngle.Sin())), 34 | difference.X.Multiply(newAngle.Sin()).Add(difference.Y.Multiply(newAngle.Cos()))); 35 | } 36 | 37 | public static TNumeric GetLengthSquared(this Vector2N vector) where TNumeric : struct, INumeric 38 | => vector.X.Multiply(vector.X).Add(vector.Y.Multiply(vector.Y)); 39 | 40 | public static TNumeric GetLength(this Vector2N vector) where TNumeric : struct, INumeric 41 | => MathN.Sqrt(vector.GetLengthSquared()); 42 | 43 | public static TNumeric DistanceFrom(this Vector2N vector, Vector2N point) where TNumeric : struct, INumeric 44 | => MathN.Sqrt(vector.X.Subtract(point.X).Square().Add(vector.Y.Subtract(point.Y).Square())); 45 | 46 | public static Vector2N Translate(this Vector2N vector, Vector2N delta) where TNumeric : struct, INumeric 47 | => new Vector2N(vector.X.Add(delta.X), vector.Y.Add(delta.Y)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Benchmarks/Jodosoft.Numerics.Benchmarks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Benchmarks/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Jodosoft.Numerics.Benchmarks": { 4 | "commandName": "Project", 5 | "commandLineArgs": "-fd" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/ByteNTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Primitives; 23 | using Jodosoft.Primitives.Tests; 24 | using Jodosoft.Testing; 25 | using Jodosoft.Testing.NewtonsoftJson; 26 | using NUnit.Framework; 27 | 28 | namespace Jodosoft.Numerics.Tests 29 | { 30 | public sealed class ByteNTests : GlobalFixtureBase 31 | { 32 | public sealed class BinaryIOTests : BinaryIOTestBase { } 33 | public sealed class FormattableTests : FormattableTestBase { } 34 | public sealed class JsonConvertTests : JsonConvertTestBase { } 35 | public sealed class NumericBitConverterTests : NumericBitConverterTestBase { } 36 | public sealed class NumericCastTests : NumericCastTestBase { } 37 | public sealed class NumericConversionConsistencyTests : NumericConversionConsistencyTestBase { } 38 | public sealed class NumericConvertTests : NumericConvertTestBase { } 39 | public sealed class NumericIntegralTests : NumericIntegralTestBase { } 40 | public sealed class NumericMathTests : NumericMathTestBase { } 41 | public sealed class NumericNonFloatingPointTests : NumericNonFloatingPointTestBase { } 42 | public sealed class NumericNonInfinityTests : NumericNonInfinityTestBase { } 43 | public sealed class NumericNonNaNTests : NumericNonNaNTestBase { } 44 | public sealed class NumericRandomTestBase : NumericRandomTestBase { } 45 | public sealed class NumericStringConvertTests : NumericStringConvertTestBase { } 46 | public sealed class NumericTests : NumericTestBase { } 47 | public sealed class NumericUnsignedTests : NumericUnsignedTestBase { } 48 | public sealed class ObjectTests : ObjectTestBase { } 49 | public sealed class SerializableTests : SerializableTestBase { } 50 | 51 | [Test, Repeat(RandomVariations)] 52 | public void IncrementOperator_RandomInputs_SameAsPlusOne() 53 | { 54 | //arrange 55 | ByteN input = Random.NextVariant(); 56 | ByteN expected = input + 1; 57 | 58 | //act 59 | input++; 60 | 61 | //assert 62 | input.Should().Be(expected); 63 | } 64 | 65 | [Test, Repeat(RandomVariations)] 66 | public void DecrementOperator_RandomInputs_SameAsMinusOne() 67 | { 68 | //arrange 69 | ByteN input = Random.NextVariant(); 70 | ByteN expected = input - 1; 71 | 72 | //act 73 | input--; 74 | 75 | //assert 76 | input.Should().Be(expected); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/Jodosoft.Numerics.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/NumericFixedPointTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Primitives; 23 | using Jodosoft.Testing; 24 | using NUnit.Framework; 25 | 26 | namespace Jodosoft.Numerics.Tests 27 | { 28 | public abstract class NumericFixedPointTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 29 | { 30 | [SetUp] 31 | public void SetUp() => Assert.That(Numeric.IsReal() && !Numeric.HasFloatingPoint()); 32 | 33 | [Test] 34 | public void GetTypeCode_AnyValue_ReturnsObject() 35 | { 36 | //arrange 37 | TNumeric input = Random.NextVariant(); 38 | 39 | //act 40 | TypeCode result = ((IConvertible)input).GetTypeCode(); 41 | 42 | //assert 43 | result.Should().Be(TypeCode.Object); 44 | } 45 | 46 | [Test, Repeat(RandomVariations)] 47 | public void ToBoolean_AnyValue_CorrectResult() 48 | { 49 | //arrange 50 | TNumeric input = Random.NextVariant(); 51 | 52 | //act 53 | bool result = ((IConvertible)input).ToBoolean(null); 54 | 55 | //assert 56 | result.Should().Be(!input.Equals(Numeric.Zero())); 57 | } 58 | 59 | [Test, Repeat(RandomVariations)] 60 | public void ToStringParse_LowMagnitude_CanRoundTrip() 61 | { 62 | //arrange 63 | TNumeric input = Random.NextVariant(Variants.LowMagnitude); 64 | 65 | //act 66 | TNumeric result = Numeric.Parse(input.ToString()); 67 | 68 | //assert 69 | result.Should().Be(input); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/NumericMathErrorNaNTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Testing; 23 | using NUnit.Framework; 24 | 25 | namespace Jodosoft.Numerics.Tests 26 | { 27 | public abstract class NumericMathErrorNaNTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 28 | { 29 | [SetUp] 30 | public void SetUp() => Assert.That(Numeric.HasNaN()); 31 | 32 | [Test] 33 | public void Sign_NaN_ThrowsArithmeticException() 34 | { 35 | //arrange 36 | TNumeric input = ConvertN.ToNumeric(float.NaN, Conversion.Cast); 37 | 38 | //act 39 | Action action = new Action(() => MathN.Sign(input)); 40 | 41 | //assert 42 | action.Should().Throw(); 43 | } 44 | 45 | [Test] 46 | public void Acos_ValueOutOfRange_ReturnsNaNOrZero() 47 | { 48 | //arrange 49 | TNumeric input; 50 | do { input = Random.NextNumeric(Generation.Extended); } 51 | while (input.IsGreaterThanOrEqualTo(Numeric.MinUnit()) && input.IsLessThanOrEqualTo(Numeric.MaxUnit())); 52 | 53 | //act 54 | TNumeric result = MathN.Acos(input); 55 | 56 | //assert 57 | Numeric.IsNaN(result).Should().BeTrue(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/NumericNaNTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using FluentAssertions; 21 | using Jodosoft.Testing; 22 | using NUnit.Framework; 23 | 24 | namespace Jodosoft.Numerics.Tests 25 | { 26 | public abstract class NumericNaNTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 27 | { 28 | [SetUp] 29 | public void SetUp() => Assert.That(Numeric.HasNaN()); 30 | 31 | [TestCase(double.PositiveInfinity, false)] 32 | [TestCase(double.NegativeInfinity, false)] 33 | [TestCase(double.NaN, true)] 34 | [TestCase(0, false)] 35 | public void IsNaN_Examples_ReturnsExpected(double value, bool expected) 36 | { 37 | //arrange 38 | TNumeric input = ConvertN.ToNumeric(value, Conversion.Cast); 39 | 40 | //act 41 | bool result = Numeric.IsNaN(input); 42 | 43 | //assert 44 | result.Should().Be(expected); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/NumericNonFloatingPointTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Testing; 23 | using NUnit.Framework; 24 | 25 | namespace Jodosoft.Numerics.Tests 26 | { 27 | public abstract class NumericNonFloatingPointTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 28 | { 29 | [SetUp] 30 | public void SetUp() => Assert.That(!Numeric.HasFloatingPoint()); 31 | 32 | [Test, Repeat(RandomVariations)] 33 | public void IsNormal_RandomValue_AlwaysFalse() 34 | { 35 | //arrange 36 | TNumeric input = Random.NextNumeric(Generation.Extended); 37 | 38 | //act 39 | bool result = Numeric.IsNormal(input); 40 | 41 | //assert 42 | result.Should().BeFalse(); 43 | } 44 | 45 | [Test, Repeat(RandomVariations)] 46 | public void IsSubnormal_RandomIntegral_AlwaysFalse() 47 | { 48 | //arrange 49 | TNumeric input = Random.NextNumeric(Generation.Extended); 50 | 51 | //act 52 | bool result = Numeric.IsSubnormal(input); 53 | 54 | //assert 55 | result.Should().BeFalse(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/NumericNonInfinityTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Primitives; 23 | using Jodosoft.Testing; 24 | using NUnit.Framework; 25 | 26 | namespace Jodosoft.Numerics.Tests 27 | { 28 | public abstract class NumericNonInfinityTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 29 | { 30 | [SetUp] 31 | public void SetUp() => Assert.That(!Numeric.HasInfinity()); 32 | 33 | [Test, Repeat(RandomVariations)] 34 | public void IsFinite_RandomValue_AlwaysTrue() 35 | { 36 | //arrange 37 | byte[] bytes = BitConverterN.GetBytes(default); 38 | Random.NextBytes(bytes); 39 | TNumeric input = BitConverterN.ToNumeric(bytes, 0); 40 | 41 | //act 42 | bool result = Numeric.IsFinite(input); 43 | 44 | //assert 45 | result.Should().BeTrue(); 46 | } 47 | 48 | [Test, Repeat(RandomVariations)] 49 | public void IsInfinity_RandomValue_AlwaysFalse() 50 | { 51 | //arrange 52 | byte[] bytes = BitConverterN.GetBytes(default); 53 | Random.NextBytes(bytes); 54 | TNumeric input = BitConverterN.ToNumeric(bytes, 0); 55 | 56 | //act 57 | bool result = Numeric.IsInfinity(input); 58 | 59 | //assert 60 | result.Should().BeFalse(); 61 | } 62 | 63 | [Test, Repeat(RandomVariations)] 64 | public void IsPositiveInfinity_RandomValue_AlwaysFalse() 65 | { 66 | //arrange 67 | byte[] bytes = BitConverterN.GetBytes(default); 68 | Random.NextBytes(bytes); 69 | TNumeric input = BitConverterN.ToNumeric(bytes, 0); 70 | 71 | //act 72 | bool result = Numeric.IsPositiveInfinity(input); 73 | 74 | //assert 75 | result.Should().BeFalse(); 76 | } 77 | 78 | [Test, Repeat(RandomVariations)] 79 | public void IsNegativeInfinity_RandomValue_AlwaysFalse() 80 | { 81 | //arrange 82 | byte[] bytes = BitConverterN.GetBytes(default); 83 | Random.NextBytes(bytes); 84 | TNumeric input = BitConverterN.ToNumeric(bytes, 0); 85 | 86 | //act 87 | bool result = Numeric.IsNegativeInfinity(input); 88 | 89 | //assert 90 | result.Should().BeFalse(); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/NumericNonNaNTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Primitives; 23 | using Jodosoft.Testing; 24 | using NUnit.Framework; 25 | 26 | namespace Jodosoft.Numerics.Tests 27 | { 28 | public abstract class NumericNonNaNTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 29 | { 30 | [SetUp] 31 | public void SetUp() => Assert.That(!Numeric.HasNaN()); 32 | 33 | [Test, Repeat(RandomVariations)] 34 | public void IsNaN_RandomValue_AlwaysFalse() 35 | { 36 | //arrange 37 | byte[] bytes = BitConverterN.GetBytes(default); 38 | Random.NextBytes(bytes); 39 | TNumeric input = BitConverterN.ToNumeric(bytes, 0); 40 | 41 | //act 42 | bool result = Numeric.IsNaN(input); 43 | 44 | //assert 45 | result.Should().BeFalse(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/NumericStringConvertTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Globalization; 22 | using FluentAssertions; 23 | using Jodosoft.Testing; 24 | using NUnit.Framework; 25 | 26 | namespace Jodosoft.Numerics.Tests 27 | { 28 | public abstract class NumericStringConvertTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 29 | { 30 | [Test, Repeat(RandomVariations)] 31 | public void Parse1_RoundTripSmallValue_CorrectResult() 32 | { 33 | //arrange 34 | TNumeric input = MathN.Round(ConvertN.ToNumeric(Random.NextDouble(-10, 10), Conversion.Clamp), 2); 35 | 36 | //act 37 | TNumeric result = Numeric.Parse(input.ToString()); 38 | 39 | //assert 40 | result.Should().Be(input); 41 | } 42 | 43 | [Test, Repeat(RandomVariations)] 44 | public void Parse1_RoundTripFormat_CorrectResult() 45 | { 46 | //arrange 47 | TNumeric input = MathN.Round(ConvertN.ToNumeric(Random.NextDouble(-10, 10), Conversion.Clamp), 2); 48 | string format = "G17"; 49 | 50 | //act 51 | TNumeric result = Numeric.Parse(input.ToString(format)); 52 | 53 | //assert 54 | result.Should().Be(input); 55 | } 56 | 57 | [Test, Repeat(RandomVariations)] 58 | public void Parse1_RoundTripFormatWithProvider_CorrectResult() 59 | { 60 | //arrange 61 | TNumeric input = MathN.Round(ConvertN.ToNumeric(Random.NextDouble(-10, 10), Conversion.Clamp), 2); 62 | string format = "G17"; 63 | 64 | //act 65 | TNumeric result = Numeric.Parse(input.ToString(format, NumberFormatInfo.InvariantInfo)); 66 | 67 | //assert 68 | result.Should().Be(input); 69 | } 70 | 71 | [Test, Repeat(RandomVariations)] 72 | public void Parse2_RoundTripFormatWithProvider_CorrectResult() 73 | { 74 | //arrange 75 | TNumeric input = MathN.Round(ConvertN.ToNumeric(Random.NextDouble(-10, 10), Conversion.Clamp), 2); 76 | string format = "G17"; 77 | NumberFormatInfo provider = NumberFormatInfo.InvariantInfo; 78 | NumberStyles numberStyles = NumberStyles.Any; 79 | 80 | //act 81 | TNumeric result = Numeric.Parse(input.ToString(format, provider), numberStyles, provider); 82 | 83 | //assert 84 | result.Should().Be(input); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/NumericUnsignedTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Testing; 23 | using NUnit.Framework; 24 | 25 | namespace Jodosoft.Numerics.Tests 26 | { 27 | public abstract class NumericUnsignedTestBase : GlobalFixtureBase where TNumeric : struct, INumeric 28 | { 29 | [SetUp] 30 | public void SetUp() => Assert.That(Numeric.IsUnsigned()); 31 | 32 | [Test] 33 | public void MinUnit_Unsigned_IsZero() 34 | { 35 | Numeric.MinUnit().Should().Be(Numeric.Zero()); 36 | } 37 | 38 | [Test] 39 | public void MinValue_Unsigned_IsZero() 40 | { 41 | Numeric.MinValue().Should().Be(Numeric.Zero()); 42 | } 43 | 44 | [Test, Repeat(RandomVariations)] 45 | public void IsNegative_RandomValue_AlwaysFalse() 46 | { 47 | //arrange 48 | TNumeric input = Random.NextNumeric(Generation.Extended); 49 | 50 | //act 51 | bool result = Numeric.IsNegative(input); 52 | 53 | //assert 54 | result.Should().BeFalse(); 55 | } 56 | 57 | [Test, Repeat(RandomVariations)] 58 | public void Abs_Unsigned_SameValue() 59 | { 60 | //arrange 61 | TNumeric input = Random.NextNumeric(Generation.Extended); 62 | 63 | //act 64 | TNumeric result = MathN.Abs(input); 65 | 66 | //assert 67 | result.Should().Be(input); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/RandomExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Numerics.Tests 23 | { 24 | public static class RandomExtensions 25 | { 26 | public static TNumeric NextNumeric(this Random random, TestBounds bounds) where TNumeric : struct, INumeric 27 | { 28 | TNumeric result; 29 | do 30 | { 31 | result = random.NextNumeric(Generation.Extended); 32 | } while ( 33 | (bounds.HasFlag(TestBounds.Positive) && result.IsLessThanOrEqualTo(Numeric.Zero())) || 34 | (bounds.HasFlag(TestBounds.HighMagnitude) && MathN.Abs(result).IsLessThan(ConvertN.ToNumeric(10, Conversion.Cast)))); 35 | 36 | if (bounds.HasFlag(TestBounds.LowSignificance)) 37 | { 38 | while (MathN.Log10(MathN.Abs(result)).IsGreaterThan(ConvertN.ToNumeric(3))) 39 | { 40 | result = result.Divide(ConvertN.ToNumeric(10, Conversion.Cast)); 41 | } 42 | result = MathN.Round(result, 2); 43 | } 44 | 45 | if (!Numeric.IsFinite(result)) 46 | { 47 | throw new InvalidOperationException(); 48 | } 49 | 50 | return result; 51 | } 52 | 53 | public static Vector2N NextVector2(this Random random, TestBounds bounds) where TNumeric : struct, INumeric 54 | { 55 | return new Vector2N( 56 | random.NextNumeric(bounds), 57 | random.NextNumeric(bounds)); 58 | } 59 | 60 | public static Vector3N NextVector3(this Random random, TestBounds bounds) where TNumeric : struct, INumeric 61 | { 62 | return new Vector3N( 63 | random.NextNumeric(bounds), 64 | random.NextNumeric(bounds), 65 | random.NextNumeric(bounds)); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/SingleMTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Numerics.Clamped; 23 | using Jodosoft.Primitives; 24 | using Jodosoft.Primitives.Tests; 25 | using Jodosoft.Testing; 26 | using Jodosoft.Testing.NewtonsoftJson; 27 | using NUnit.Framework; 28 | 29 | namespace Jodosoft.Numerics.Tests 30 | { 31 | public sealed class SingleMTests : GlobalFixtureBase 32 | { 33 | public sealed class BinaryIOTests : BinaryIOTestBase { } 34 | public sealed class CheckedNumericConversionTests : CheckedNumericConversionTestBase { } 35 | public sealed class CheckedNumericTests : CheckedNumericTestBase { } 36 | public sealed class FormattableTests : FormattableTestBase { } 37 | public sealed class JsonConvertTests : JsonConvertTestBase { } 38 | public sealed class NumericBitConverterTests : NumericBitConverterTestBase { } 39 | public sealed class NumericCastTests : NumericCastTestBase { } 40 | public sealed class NumericConvertTests : NumericConvertTestBase { } 41 | public sealed class NumericFloatingPointTests : NumericFloatingPointTestBase { } 42 | public sealed class NumericMathTests : NumericMathTestBase { } 43 | public sealed class NumericRandomTestBase : NumericRandomTestBase { } 44 | public sealed class NumericSignedTests : NumericSignedTestBase { } 45 | public sealed class NumericStringConvertTests : NumericStringConvertTestBase { } 46 | public sealed class NumericTests : NumericTestBase { } 47 | public sealed class ObjectTests : ObjectTestBase { } 48 | public sealed class SerializableTests : SerializableTestBase { } 49 | 50 | [Test, Repeat(RandomVariations)] 51 | public void IncrementOperator_RandomInputs_SameAsPlusOne() 52 | { 53 | //arrange 54 | SingleM input = Random.NextVariant(Variants.NonError); 55 | SingleM expected = input + 1; 56 | 57 | //act 58 | input++; 59 | 60 | //assert 61 | input.Should().Be(expected); 62 | } 63 | 64 | [Test, Repeat(RandomVariations)] 65 | public void DecrementOperator_RandomInputs_SameAsMinusOne() 66 | { 67 | //arrange 68 | SingleM input = Random.NextVariant(Variants.NonError); 69 | SingleM expected = input - 1; 70 | 71 | //act 72 | input--; 73 | 74 | //assert 75 | input.Should().Be(expected); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/TestBounds.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Numerics.Tests 23 | { 24 | [Flags] 25 | public enum TestBounds 26 | { 27 | LowSignificance = 1, 28 | HighMagnitude = 2, 29 | Positive = 4, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/TestUtilities.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Numerics.Tests 23 | { 24 | public static class TestUtilities 25 | { 26 | public static double ReduceSignificance(TNumeric value) where TNumeric : struct, INumeric 27 | { 28 | double result = Math.Round(ConvertN.ToDouble(value, Conversion.Cast), 6); 29 | int log10 = (int)Math.Log10(Math.Abs(result / 10)); 30 | if (log10 < -1) result *= 1000; 31 | else if (log10 > 3) result /= Math.Pow(10, log10 - 3); 32 | 33 | if (!Numeric.IsFinite(ConvertN.ToNumeric(result, Conversion.Cast))) 34 | { 35 | throw new InvalidOperationException(); 36 | } 37 | 38 | return Math.Round(result, 6); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/UnitNTest.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Primitives.Tests; 21 | using Jodosoft.Testing; 22 | 23 | namespace Jodosoft.Numerics.Tests 24 | { 25 | public static class UnitNTest 26 | { 27 | public sealed class FixedPointBinaryIOTests : BinaryIOTestBase> { } 28 | public sealed class FixedPointFormattableTests : FormattableTestBase> { } 29 | public sealed class FixedPointObjectTests : ObjectTestBase> { } 30 | public sealed class FixedPointSerializableTests : SerializableTestBase> { } 31 | public sealed class FixedPointUnitTests : UnitNTestBase { } 32 | public sealed class FloatingPointBinaryIOTests : BinaryIOTestBase> { } 33 | public sealed class FloatingPointFormattableTests : FormattableTestBase> { } 34 | public sealed class FloatingPointObjectTests : ObjectTestBase> { } 35 | public sealed class FloatingPointSerializableTests : SerializableTestBase> { } 36 | public sealed class FloatingPointUnitTests : UnitNTestBase { } 37 | public sealed class UnsignedIntegralBinaryIOTests : BinaryIOTestBase> { } 38 | public sealed class UnsignedIntegralFormattableTests : FormattableTestBase> { } 39 | public sealed class UnsignedIntegralObjectTests : ObjectTestBase> { } 40 | public sealed class UnsignedIntegralSerializableTests : SerializableTestBase> { } 41 | public sealed class UnsignedIntegralUnitTests : UnitNTestBase { } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/Vector2NTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using FluentAssertions; 21 | using Jodosoft.Primitives.Tests; 22 | using Jodosoft.Testing; 23 | using NUnit.Framework; 24 | 25 | namespace Jodosoft.Numerics.Tests 26 | { 27 | public class Vector2NTests : GlobalFixtureBase 28 | { 29 | public sealed class FixedPointBinaryIOTests : BinaryIOTestBase> { } 30 | public sealed class FixedPointFormattableTests : FormattableTestBase> { } 31 | public sealed class FixedPointObjectTests : ObjectTestBase> { } 32 | public sealed class FixedPointSerializableTests : SerializableTestBase> { } 33 | public sealed class FixedPointVector2Tests : Vector2NTestBase { } 34 | public sealed class FloatingPointBinaryIOTests : BinaryIOTestBase> { } 35 | public sealed class FloatingPointFormattableTests : FormattableTestBase> { } 36 | public sealed class FloatingPointObjectTests : ObjectTestBase> { } 37 | public sealed class FloatingPointSerializableTests : SerializableTestBase> { } 38 | public sealed class FloatingPointVector2Tests : Vector2NTestBase { } 39 | public sealed class UnsignedIntegralBinaryIOTests : BinaryIOTestBase> { } 40 | public sealed class UnsignedIntegralFormattableTests : FormattableTestBase> { } 41 | public sealed class UnsignedIntegralObjectTests : ObjectTestBase> { } 42 | public sealed class UnsignedIntegralSerializableTests : SerializableTestBase> { } 43 | public sealed class UnsignedIntegralVector2Tests : Vector2NTestBase { } 44 | 45 | [Test] 46 | public void Dot_WorkedExample_CorrectResult() 47 | { 48 | //arrange 49 | //act 50 | SingleN result = Vector2N.Dot( 51 | new Vector2N(2, -4), new Vector2N(-8, 104)); 52 | 53 | //assert 54 | result.Should().Be(-432); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics.Tests/Vector3NTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using Jodosoft.Primitives.Tests; 21 | using Jodosoft.Testing; 22 | 23 | namespace Jodosoft.Numerics.Tests 24 | { 25 | public static class Vector3NTests 26 | { 27 | public sealed class FixedPointBinaryIOTests : BinaryIOTestBase> { } 28 | public sealed class FixedPointFormattableTests : FormattableTestBase> { } 29 | public sealed class FixedPointObjectTests : ObjectTestBase> { } 30 | public sealed class FixedPointSerializableTests : SerializableTestBase> { } 31 | public sealed class FixedPointVector3Tests : Vector3NTestBase { } 32 | public sealed class FloatingPointBinaryIOTests : BinaryIOTestBase> { } 33 | public sealed class FloatingPointFormattableTests : FormattableTestBase> { } 34 | public sealed class FloatingPointObjectTests : ObjectTestBase> { } 35 | public sealed class FloatingPointSerializableTests : SerializableTestBase> { } 36 | public sealed class FloatingPointVector3Tests : Vector3NTestBase { } 37 | public sealed class UnsignedIntegralBinaryIOTests : BinaryIOTestBase> { } 38 | public sealed class UnsignedIntegralFormattableTests : FormattableTestBase> { } 39 | public sealed class UnsignedIntegralObjectTests : ObjectTestBase> { } 40 | public sealed class UnsignedIntegralSerializableTests : SerializableTestBase> { } 41 | public sealed class UnsignedIntegralVector3Tests : Vector3NTestBase { } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/Clamped/ConversionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Numerics.Clamped 23 | { 24 | internal static class ConversionExtensions 25 | { 26 | public static Conversion Clamped(this Conversion conversion) => conversion switch 27 | { 28 | Conversion.Default => Conversion.Clamp, 29 | Conversion.Clamp => Conversion.Clamp, 30 | Conversion.Cast => Conversion.CastClamp, 31 | Conversion.CastClamp => Conversion.CastClamp, 32 | _ => throw new ArgumentOutOfRangeException(nameof(conversion)), 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/Conversion.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | namespace Jodosoft.Numerics 21 | { 22 | public enum Conversion 23 | { 24 | Default = 0, 25 | Clamp = 1, 26 | Cast = 2, 27 | CastClamp = 3 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/Generation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | namespace Jodosoft.Numerics 21 | { 22 | /// 23 | /// Specifies how numbers should be randomly generated. 24 | /// 25 | public enum Generation : byte 26 | { 27 | /// 28 | /// Numbers will be generated according the conventions established by : 29 | /// 30 | /// Lower bounds are inclusive and upper bounds are exclusive. 31 | /// An is thrown if the lower bound is greater than the upper bound. 32 | /// If no lower bound is specified then values returned are greater than or equal to zero. 33 | /// If no upper bound is specified then values returned are less than the MaxValue constant for integral types, otherwise less than one. 34 | /// If the bounds are equal then the lower bound is returned. 35 | /// 36 | /// 37 | Default = 0, 38 | 39 | /// 40 | /// Numbers will be generated with extended bounds: 41 | /// 42 | /// Both upper and lower bounds are inclusive. 43 | /// The upper and lower bounds will be swapped if specified in reverse order. 44 | /// If no lower bound is specified then values returned are greater than or equal to the MinValue constant. 45 | /// If no upper bound is specified then values returned are less than or equal to the MaxValue constant. 46 | /// If the bounds are equal then the lower bound is returned. 47 | /// 48 | /// 49 | Extended = 1 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/IConvert.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | namespace Jodosoft.Numerics 21 | { 22 | /// 23 | /// Converts objects to or from base data types. 24 | /// 25 | /// The type of object that can be converted. 26 | public interface IConvert 27 | { 28 | bool ToBoolean(TNumeric value); 29 | byte ToByte(TNumeric value, Conversion mode); 30 | decimal ToDecimal(TNumeric value, Conversion mode); 31 | double ToDouble(TNumeric value, Conversion mode); 32 | float ToSingle(TNumeric value, Conversion mode); 33 | int ToInt32(TNumeric value, Conversion mode); 34 | long ToInt64(TNumeric value, Conversion mode); 35 | short ToInt16(TNumeric value, Conversion mode); 36 | string ToString(TNumeric value); 37 | 38 | TNumeric ToNumeric(bool value); 39 | TNumeric ToNumeric(byte value, Conversion mode); 40 | TNumeric ToNumeric(decimal value, Conversion mode); 41 | TNumeric ToNumeric(double value, Conversion mode); 42 | TNumeric ToNumeric(float value, Conversion mode); 43 | TNumeric ToNumeric(int value, Conversion mode); 44 | TNumeric ToNumeric(long value, Conversion mode); 45 | TNumeric ToNumeric(short value, Conversion mode); 46 | TNumeric ToNumeric(string value); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/IConvertExtended.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Numerics 23 | { 24 | /// 25 | /// Converts objects to or from non-CLS compliant base data types. 26 | /// 27 | /// The type of object that can be converted. 28 | [CLSCompliant(false)] 29 | public interface IConvertExtended 30 | { 31 | sbyte ToSByte(TNumeric value, Conversion mode); 32 | uint ToUInt32(TNumeric value, Conversion mode); 33 | ulong ToUInt64(TNumeric value, Conversion mode); 34 | ushort ToUInt16(TNumeric value, Conversion mode); 35 | 36 | TNumeric ToValue(sbyte value, Conversion mode); 37 | TNumeric ToNumeric(ushort value, Conversion mode); 38 | TNumeric ToNumeric(ulong value, Conversion mode); 39 | TNumeric ToNumeric(uint value, Conversion mode); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/INumericExtended.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Diagnostics.CodeAnalysis; 22 | using Jodosoft.Primitives; 23 | 24 | namespace Jodosoft.Numerics 25 | { 26 | /// 27 | /// An extended version of that supports non-CLS-compliant 28 | /// operations such as conversion to unsigned numbers. 29 | /// 30 | /// The type that implements 31 | [CLSCompliant(false)] 32 | [SuppressMessage("csharpsquid", "S3444:Interfaces should not simply inherit from base interfaces with colliding members", Justification = "By design - IProvider instances are accessed via static classes")] 33 | public interface INumericExtended : 34 | INumeric, 35 | IConvertible, 36 | IProvider> 37 | where TSelf : struct, INumericExtended 38 | { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/INumericRandom.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Numerics 23 | { 24 | public interface INumericRandom 25 | { 26 | TNumeric Generate(Random random); 27 | TNumeric Generate(Random random, TNumeric maxValue); 28 | TNumeric Generate(Random random, TNumeric minValue, TNumeric maxValue); 29 | TNumeric Generate(Random random, Generation mode); 30 | TNumeric Generate(Random random, TNumeric minValue, TNumeric maxValue, Generation mode); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/INumericStatic.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Globalization; 22 | 23 | namespace Jodosoft.Numerics 24 | { 25 | public interface INumericStatic 26 | { 27 | bool IsSigned { get; } 28 | bool IsReal { get; } 29 | bool HasNaN { get; } 30 | bool HasInfinity { get; } 31 | bool HasFloatingPoint { get; } 32 | 33 | TNumeric Epsilon { get; } 34 | TNumeric MaxUnit { get; } 35 | TNumeric MaxValue { get; } 36 | TNumeric MinUnit { get; } 37 | TNumeric MinValue { get; } 38 | TNumeric One { get; } 39 | TNumeric Zero { get; } 40 | 41 | bool IsFinite(TNumeric x); 42 | bool IsInfinity(TNumeric x); 43 | bool IsNaN(TNumeric x); 44 | bool IsNegative(TNumeric x); 45 | bool IsNegativeInfinity(TNumeric x); 46 | bool IsNormal(TNumeric x); 47 | bool IsPositiveInfinity(TNumeric x); 48 | bool IsSubnormal(TNumeric x); 49 | 50 | TNumeric Parse(string s, NumberStyles? style, IFormatProvider? provider); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/Jodosoft.Numerics.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/NumericExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Diagnostics.CodeAnalysis; 21 | using System.Runtime.CompilerServices; 22 | 23 | namespace Jodosoft.Numerics 24 | { 25 | public static class NumericExtensions 26 | { 27 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 28 | [SuppressMessage("Naming", "CA1720:Identifier contains type name", Justification = "Appropriate use according to the documentation of CA1720.")] 29 | public static TNumeric Double(this TNumeric n) where TNumeric : struct, INumeric 30 | { 31 | return n.Multiply(Numeric.One().Add(Numeric.One())); 32 | } 33 | 34 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 35 | public static TNumeric Half(this TNumeric n) where TNumeric : struct, INumeric 36 | { 37 | return n.Divide(Numeric.One().Add(Numeric.One())); 38 | } 39 | 40 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 41 | public static TNumeric Square(this TNumeric n) where TNumeric : struct, INumeric 42 | { 43 | return n.Multiply(n); 44 | } 45 | 46 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 47 | public static TNumeric Cube(this TNumeric n) where TNumeric : struct, INumeric 48 | { 49 | return n.Multiply(n).Multiply(n); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/README.md: -------------------------------------------------------------------------------- 1 | Non-overflowing numbers, fixed-point numbers, structures and utilities. 2 | 3 | See: https://github.com/Jodosoft/Libraries/#numerics -------------------------------------------------------------------------------- /src/Jodosoft.Numerics/TAGS.md: -------------------------------------------------------------------------------- 1 | numeric, numerics, number, numbers, math, maths, arithmetic, fixed, point, fixed-point, fix, overflow, non-overflowing, checked, jodo, jodosoft -------------------------------------------------------------------------------- /src/Jodosoft.Primitives.Benchmarks/Jodosoft.Primitives.Benchmarks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives.Tests/BinaryIOTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.IO; 22 | using System.Linq; 23 | using FluentAssertions; 24 | using Jodosoft.Testing; 25 | using NUnit.Framework; 26 | 27 | namespace Jodosoft.Primitives.Tests 28 | { 29 | /// 30 | /// Provides common test methods for types that implement 31 | /// 32 | /// The type of struct. 33 | public abstract class BinaryIOTestBase : GlobalFixtureBase where T : struct, IProvider>, IProvider> 34 | { 35 | [Test, Repeat(RandomVariations)] 36 | public void Serialise_RandomValues_ReadsBackSameValues() 37 | { 38 | //arrange 39 | T[] inputs = Enumerable 40 | .Range(0, Random.Next(10)) 41 | .Select(_ => Random.NextVariant(Variants.NonError)) 42 | .ToArray(); 43 | 44 | //act 45 | byte[] buffer = inputs.SelectMany(x => BinaryConvert.Serialize(x)).ToArray(); 46 | using Stream stream = new MemoryStream(buffer); 47 | using BinaryReader reader = new BinaryReader(stream); 48 | stream.Position = 0; 49 | T[] results = new T[inputs.Length]; 50 | for (int i = 0; i < results.Length; i++) 51 | { 52 | results[i] = reader.Read(); 53 | } 54 | 55 | //assert 56 | results.Should().BeEquivalentTo(inputs); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives.Tests/DynamicInvokeTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Testing; 23 | using NUnit.Framework; 24 | 25 | namespace Jodosoft.Primitives.Tests 26 | { 27 | public sealed class DynamicInvokeTests : GlobalFixtureBase 28 | { 29 | [Test] 30 | public void OperatorMethods_TypeWithoutOperatorDefinition_ThrowsInvalidOperationException() 31 | { 32 | //arrange 33 | //act 34 | Func[] actions = new[] { 35 | new Func(() => DynamicInvoke.AdditionOperator(string.Empty, string.Empty)), 36 | new Func(() => DynamicInvoke.BitwiseComplementOperator(string.Empty)), 37 | new Func(() => DynamicInvoke.DecrementOperator(string.Empty)), 38 | new Func(() => DynamicInvoke.DivisionOperator(string.Empty, string.Empty)), 39 | new Func(() => DynamicInvoke.GreaterThanOperator(string.Empty, string.Empty)), 40 | new Func(() => DynamicInvoke.GreaterThanOrEqualOperator(string.Empty, string.Empty)), 41 | new Func(() => DynamicInvoke.IncrementOperator(string.Empty)), 42 | new Func(() => DynamicInvoke.LeftShiftOperator(string.Empty, Random.Next())), 43 | new Func(() => DynamicInvoke.LessThanOperator(string.Empty, string.Empty)), 44 | new Func(() => DynamicInvoke.LessThanOrEqualOperator(string.Empty, string.Empty)), 45 | new Func(() => DynamicInvoke.LogicalAndOperator(string.Empty, string.Empty)), 46 | new Func(() => DynamicInvoke.LogicalExclusiveOrOperator(string.Empty, string.Empty)), 47 | new Func(() => DynamicInvoke.LogicalOrOperator(string.Empty, string.Empty)), 48 | new Func(() => DynamicInvoke.MultiplicationOperator(string.Empty, string.Empty)), 49 | new Func(() => DynamicInvoke.RemainderOperator(string.Empty, string.Empty)), 50 | new Func(() => DynamicInvoke.RightShiftOperator(string.Empty, Random.Next())), 51 | new Func(() => DynamicInvoke.SubtractionOperator(string.Empty, string.Empty)), 52 | new Func(() => DynamicInvoke.UnaryMinusOperator(string.Empty)), 53 | new Func(() => DynamicInvoke.UnaryPlusOperator(string.Empty)) 54 | }; 55 | 56 | //assert 57 | actions[0].Should().Throw().Which.Message.Should().Contain("not defined"); 58 | AssertSame.Outcome(actions); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives.Tests/FuncExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Testing; 23 | using NUnit.Framework; 24 | 25 | namespace Jodosoft.Primitives.Tests 26 | { 27 | public sealed class FuncExtensionsTests : GlobalFixtureBase 28 | { 29 | [Test] 30 | public void Try1_ReferenceTypeNoException_ReturnsSameReference() 31 | { 32 | //arrange 33 | object expected = new object(); 34 | Func function = new Func(() => expected); 35 | 36 | //act 37 | bool result = FuncExtensions.Try(function, out object outResult); 38 | 39 | //assert 40 | result.Should().BeTrue(); 41 | outResult.Should().BeSameAs(expected); 42 | } 43 | 44 | [Test] 45 | public void Try1_ValueTypeNoException_ReturnsSameValue() 46 | { 47 | //arrange 48 | int expected = Random.Next(); 49 | Func function = new Func(() => expected); 50 | 51 | //act 52 | bool result = FuncExtensions.Try(function, out int outResult); 53 | 54 | //assert 55 | result.Should().BeTrue(); 56 | outResult.Should().Be(expected); 57 | } 58 | 59 | [Test] 60 | public void Try1_ReferenceTypeWithException_ReturnsNull() 61 | { 62 | //arrange 63 | Func function = new Func(() => throw new InvalidOperationException()); 64 | 65 | //act 66 | bool result = FuncExtensions.Try(function, out object outResult); 67 | 68 | //assert 69 | result.Should().BeFalse(); 70 | outResult.Should().BeNull(); 71 | } 72 | 73 | [Test] 74 | public void Try1_ValueTypeWithException_ReturnsDefault() 75 | { 76 | //arrange 77 | Func function = new Func(() => throw new InvalidOperationException()); 78 | 79 | //act 80 | bool result = FuncExtensions.Try(function, out int outResult); 81 | 82 | //assert 83 | result.Should().BeFalse(); 84 | outResult.Should().Be(0); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives.Tests/Jodosoft.Primitives.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives.Tests/RandomExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Linq; 22 | using FluentAssertions; 23 | using Jodosoft.Testing; 24 | using NUnit.Framework; 25 | 26 | namespace Jodosoft.Primitives.Tests 27 | { 28 | public sealed class RandomExtensionsTests : GlobalFixtureBase 29 | { 30 | public enum Test 31 | { 32 | A, 33 | B 34 | } 35 | 36 | [Test] 37 | public void NextEnum_OnlyValidValues() 38 | { 39 | //arrange 40 | //act 41 | Test[] results = Enumerable.Range(0, 100) 42 | .Select(_ => Random.NextEnum()).ToArray(); 43 | 44 | //assert 45 | results.Distinct().Should().OnlyContain(x => x == Test.A || x == Test.B); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/BinaryConvert.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.IO; 23 | 24 | namespace Jodosoft.Primitives 25 | { 26 | public static class BinaryConvert 27 | { 28 | public static byte[] Serialize(IEnumerable values) where T : struct, IProvider> 29 | { 30 | if (values == null) throw new ArgumentNullException(nameof(values)); 31 | using IEnumerator enumerator = values.GetEnumerator(); 32 | if (!enumerator.MoveNext()) throw new InvalidOperationException("Sequence contains no elements"); 33 | 34 | using Stream stream = new MemoryStream(); 35 | using BinaryWriter writer = new BinaryWriter(stream); 36 | while (enumerator.MoveNext()) 37 | { 38 | DefaultProvider>.Instance.Write(writer, enumerator.Current); 39 | } 40 | stream.Position = 0; 41 | byte[] result = new byte[stream.Length]; 42 | _ = stream.Read(result, 0, result.Length); 43 | return result; 44 | } 45 | 46 | public static byte[] Serialize(T value) where T : struct, IProvider> 47 | { 48 | using Stream stream = new MemoryStream(); 49 | using BinaryWriter writer = new BinaryWriter(stream); 50 | DefaultProvider>.Instance.Write(writer, value); 51 | stream.Position = 0; 52 | byte[] result = new byte[stream.Length]; 53 | _ = stream.Read(result, 0, result.Length); 54 | return result; 55 | } 56 | 57 | public static T Deserialize(byte[] buffer, int offset) where T : struct, IProvider> 58 | { 59 | using Stream stream = new MemoryStream(buffer, offset, buffer.Length - offset); 60 | using BinaryReader reader = new BinaryReader(stream); 61 | stream.Position = 0; 62 | T result = DefaultProvider>.Instance.Read(reader); 63 | return result; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/BinaryReaderExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.IO; 21 | using System.Runtime.CompilerServices; 22 | 23 | namespace Jodosoft.Primitives 24 | { 25 | public static class BinaryReaderExtensions 26 | { 27 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 28 | public static T Read(this BinaryReader reader) where T : struct, IProvider> 29 | => DefaultProvider>.Instance.Read(reader); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/BinaryWriterExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.IO; 21 | using System.Runtime.CompilerServices; 22 | 23 | namespace Jodosoft.Primitives 24 | { 25 | public static class BinaryWriterExtensions 26 | { 27 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 28 | public static void Write(this BinaryWriter writer, T value) where T : struct, IProvider> 29 | => DefaultProvider>.Instance.Write(writer, value); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/BitOperations.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Primitives 23 | { 24 | // This class will replace the version the Jodosoft.Numerics namespace in version 2.0 25 | internal static class BitOperations 26 | { 27 | private const string IndexOutOfRange = "Index was out of range. Must be non-negative and less than the size of the collection."; 28 | private const string NotLongEnough = "Destination array is not long enough to copy all the items in the collection. Check array index and length."; 29 | 30 | public static byte[] GetBytes(decimal value) 31 | { 32 | byte[] result = new byte[sizeof(decimal)]; 33 | int[] parts = decimal.GetBits(value); 34 | Buffer.BlockCopy(parts, 0, result, 0, result.Length); 35 | return result; 36 | } 37 | 38 | public static decimal ToDecimal(byte[] value, int startIndex) 39 | { 40 | if (value == null) throw new ArgumentNullException(nameof(value)); 41 | 42 | if (startIndex >= value.Length) throw new ArgumentOutOfRangeException(nameof(startIndex), startIndex, IndexOutOfRange); 43 | 44 | if (startIndex > value.Length - sizeof(decimal)) throw new ArgumentException(NotLongEnough, nameof(value)); 45 | 46 | int part0 = BitConverter.ToInt32(value, startIndex); 47 | int part1 = BitConverter.ToInt32(value, startIndex + sizeof(int)); 48 | int part2 = BitConverter.ToInt32(value, startIndex + sizeof(int) + sizeof(int)); 49 | int part3 = BitConverter.ToInt32(value, startIndex + sizeof(int) + sizeof(int) + sizeof(int)); 50 | 51 | bool sign = (part3 & 0x80000000) != 0; 52 | byte scale = (byte)((part3 >> 16) & 0x7F); 53 | 54 | decimal result = new decimal(part0, part1, part2, sign, scale); 55 | return result; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/Compatibility/BitConverterShim.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Diagnostics.CodeAnalysis; 22 | using System.Runtime.CompilerServices; 23 | 24 | namespace Jodosoft.Primitives.Compatibility 25 | { 26 | [SuppressMessage("csharpsquid", "S6640:Using unsafe code blocks is security-sensitive.", Justification = "Shims using verified .NET implementations.")] 27 | public static class BitConverterShim 28 | { 29 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 30 | public static unsafe int SingleToInt32Bits(float value) 31 | { 32 | #if NETSTANDARD2_1 33 | return BitConverter.SingleToInt32Bits(value); 34 | #else 35 | return *(int*)&value; 36 | #endif 37 | } 38 | 39 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 40 | public static unsafe float Int32BitsToSingle(int value) 41 | { 42 | #if NETSTANDARD2_1 43 | return BitConverter.Int32BitsToSingle(value); 44 | #else 45 | return *(float*)&value; 46 | #endif 47 | } 48 | 49 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 50 | public static unsafe long DoubleToInt64Bits(double value) 51 | { 52 | #if NETSTANDARD2_1 53 | return BitConverter.DoubleToInt64Bits(value); 54 | #else 55 | return *(long*)&value; 56 | #endif 57 | } 58 | 59 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 60 | public static unsafe double Int64BitsToDouble(long value) 61 | { 62 | #if NETSTANDARD2_1 63 | return BitConverter.Int64BitsToDouble(value); 64 | #else 65 | return *(double*)&value; 66 | #endif 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/Compatibility/DoubleShim.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Diagnostics.CodeAnalysis; 21 | using System.Runtime.CompilerServices; 22 | 23 | namespace Jodosoft.Primitives.Compatibility 24 | { 25 | 26 | [SuppressMessage("csharpsquid", "S6640:Using unsafe code blocks is security-sensitive.", Justification = "Shims using verified .NET implementations.")] 27 | public static class DoubleShim 28 | { 29 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 30 | public static bool IsFinite(double d) 31 | { 32 | #if NETSTANDARD2_1_OR_GREATER 33 | return double.IsFinite(d); 34 | #else 35 | long bits = BitConverterShim.DoubleToInt64Bits(d); 36 | return (bits & 0x7FFFFFFFFFFFFFFF) < 0x7FF0000000000000; 37 | #endif 38 | } 39 | 40 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 41 | public static unsafe bool IsNegative(double d) 42 | { 43 | #if NETSTANDARD2_1_OR_GREATER 44 | return double.IsNegative(d); 45 | #else 46 | return BitConverterShim.DoubleToInt64Bits(d) < 0; 47 | #endif 48 | } 49 | 50 | public static unsafe bool IsNormal(double d) 51 | { 52 | #if NETSTANDARD2_1_OR_GREATER 53 | return double.IsNormal(d); 54 | #else 55 | long bits = BitConverterShim.DoubleToInt64Bits(d); 56 | bits &= 0x7FFFFFFFFFFFFFFF; 57 | return bits < 0x7FF0000000000000 && bits != 0 && (bits & 0x7FF0000000000000) != 0; 58 | #endif 59 | } 60 | 61 | public static unsafe bool IsSubnormal(double d) 62 | { 63 | #if NETSTANDARD2_1_OR_GREATER 64 | return double.IsSubnormal(d); 65 | #else 66 | long bits = BitConverterShim.DoubleToInt64Bits(d); 67 | bits &= 0x7FFFFFFFFFFFFFFF; 68 | return bits < 0x7FF0000000000000 && bits != 0 && (bits & 0x7FF0000000000000) == 0; 69 | #endif 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/Compatibility/SingleShim.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Diagnostics.CodeAnalysis; 21 | using System.Runtime.CompilerServices; 22 | 23 | namespace Jodosoft.Primitives.Compatibility 24 | { 25 | 26 | [SuppressMessage("csharpsquid", "S6640:Using unsafe code blocks is security-sensitive.", Justification = "Shims using verified .NET implementations.")] 27 | public static class SingleShim 28 | { 29 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 30 | public static bool IsFinite(float f) 31 | { 32 | #if NETSTANDARD2_1 33 | return float.IsFinite(f); 34 | #else 35 | int bits = BitConverterShim.SingleToInt32Bits(f); 36 | return (bits & 0x7FFFFFFF) < 0x7F800000; 37 | #endif 38 | } 39 | 40 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 41 | public static unsafe bool IsNegative(float f) 42 | { 43 | #if NETSTANDARD2_1 44 | return float.IsNegative(f); 45 | #else 46 | return BitConverterShim.SingleToInt32Bits(f) < 0; 47 | #endif 48 | } 49 | 50 | public static unsafe bool IsNormal(float f) 51 | { 52 | #if NETSTANDARD2_1 53 | return float.IsNormal(f); 54 | #else 55 | int bits = BitConverterShim.SingleToInt32Bits(f); 56 | bits &= 0x7FFFFFFF; 57 | return bits < 0x7F800000 && bits != 0 && (bits & 0x7F800000) != 0; 58 | #endif 59 | } 60 | 61 | public static unsafe bool IsSubnormal(float f) 62 | { 63 | #if NETSTANDARD2_1 64 | return float.IsSubnormal(f); 65 | #else 66 | int bits = BitConverterShim.SingleToInt32Bits(f); 67 | bits &= 0x7FFFFFFF; 68 | return bits < 0x7F800000 && bits != 0 && (bits & 0x7F800000) == 0; 69 | #endif 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/Compatibility/ValueTupleShim.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Runtime.CompilerServices; 21 | 22 | namespace Jodosoft.Primitives.Compatibility 23 | { 24 | public static class ValueTupleShim 25 | { 26 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 27 | public static void Swap(ref T value1, ref T value2) 28 | { 29 | #if NETSTANDARD2_0_OR_GREATER 30 | (value2, value1) = (value1, value2); 31 | #else 32 | #pragma warning disable IDE0180 // Use tuple to swap values 33 | T temp = value1; 34 | #pragma warning restore IDE0180 // Use tuple to swap values 35 | value1 = value2; 36 | value2 = temp; 37 | #endif 38 | } 39 | 40 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 41 | public static void Swap(bool swap, ref T value1, ref T value2) 42 | { 43 | if (swap) 44 | { 45 | #if NETSTANDARD2_0_OR_GREATER 46 | (value2, value1) = (value1, value2); 47 | #else 48 | #pragma warning disable IDE0180 // Use tuple to swap values 49 | T temp = value1; 50 | #pragma warning restore IDE0180 // Use tuple to swap values 51 | value1 = value2; 52 | value2 = temp; 53 | #endif 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/DefaultProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | namespace Jodosoft.Primitives 21 | { 22 | public static class DefaultProvider where TProvider : struct, IProvider 23 | { 24 | public static readonly T Instance = default(TProvider).GetInstance(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/FuncExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Primitives 23 | { 24 | public static class FuncExtensions 25 | { 26 | public static bool Try(this Func function, out TResult result) 27 | { 28 | try 29 | { 30 | result = function(); 31 | return true; 32 | } 33 | catch 34 | { 35 | #nullable disable 36 | result = default; 37 | #nullable restore 38 | return false; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/IBinaryIO.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.IO; 22 | 23 | namespace Jodosoft.Primitives 24 | { 25 | /// 26 | /// Provides support for reading and writing types in binary using and . 27 | /// 28 | /// The type of object to read and write in binary. 29 | public interface IBinaryIO 30 | { 31 | /// 32 | /// Reads a value of from binary using . 33 | /// 34 | /// The reader to use to read. 35 | /// A value of . 36 | /// The end of the stream is reached. 37 | /// The stream is closed. 38 | /// An I/O error occurred. 39 | T Read(BinaryReader reader); 40 | 41 | /// 42 | /// Writes a value of in binary using . 43 | /// 44 | /// The writer to use. 45 | /// The value to write in binary. 46 | /// 47 | /// The stream is closed. 48 | /// An I/O error occurred. 49 | void Write(BinaryWriter writer, T value); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/IProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | namespace Jodosoft.Primitives 21 | { 22 | /// 23 | /// Provides a mechanism for retrieving an instance of a type. 24 | /// 25 | /// The type for which to provide an instance. 26 | public interface IProvider 27 | { 28 | /// 29 | /// Returns an instance of . 30 | /// 31 | /// An instance of . 32 | T GetInstance(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/IVariantRandom.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Primitives 23 | { 24 | /// 25 | /// Provides support for pseudo-random generation of variants of a type using . 26 | /// 27 | /// The type for which to generate variants. 28 | /// 29 | public interface IVariantRandom 30 | { 31 | /// 32 | /// Returns a random value of matching one of the specified variants. 33 | /// 34 | /// The instance of to use for supporting pseudo-random number generation. 35 | /// A bitwise combination of the enumeration values that specify which variants of may be generated. 36 | /// The value of that was generated. 37 | /// is equal to . 38 | T Generate(Random random, Variants variants); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/Jodosoft.Primitives.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | true 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/README.md: -------------------------------------------------------------------------------- 1 | Utilities, abstractions and shims used throughout The Jodosoft libraries. 2 | 3 | See: https://github.com/Jodosoft/Libraries/#primitives -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/RandomExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Diagnostics; 23 | using System.Runtime.CompilerServices; 24 | 25 | namespace Jodosoft.Primitives 26 | { 27 | public static class RandomExtensions 28 | { 29 | public static T Choose(this Random random, T item, params T[] items) 30 | { 31 | if (items != null && items.Length > 0) 32 | { 33 | int index = random.Next(0, items.Length + 1); 34 | return index == items.Length ? item : items[index]; 35 | } 36 | return item; 37 | } 38 | 39 | public static T NextElement(this Random random, IList list) 40 | { 41 | if (list == null) throw new ArgumentNullException(nameof(list)); 42 | if (list.Count == 0) throw new ArgumentException("Must not be empty.", nameof(list)); 43 | return list[random.Next(list.Count)]; 44 | } 45 | 46 | #if HAS_SPANS 47 | public static T NextElement(this Random random, Span span) 48 | => span[random.Next(0, span.Length)]; 49 | 50 | public static T NextElement(this Random random, ReadOnlySpan span) 51 | => span[random.Next(0, span.Length)]; 52 | #endif 53 | 54 | public static byte[] NextBytes(this Random random, int count) 55 | { 56 | byte[]? bytes = new byte[count]; 57 | random.NextBytes(bytes); 58 | return bytes; 59 | } 60 | 61 | public static TEnum NextEnum(this Random random) where TEnum : Enum 62 | { 63 | Array? values = Enum.GetValues(typeof(TEnum)); 64 | return (TEnum)values.GetValue(random.Next(0, values.Length)); 65 | } 66 | 67 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 68 | public static bool NextBoolean(this Random random) 69 | => random.Next(0, 2) == 1; 70 | 71 | [DebuggerStepThrough] 72 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 73 | public static T NextVariant(this Random random) where T : struct, IProvider> 74 | => DefaultProvider>.Instance.Generate(random, Variants.All); 75 | 76 | [DebuggerStepThrough] 77 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 78 | public static T NextVariant(this Random random, Variants variants) where T : struct, IProvider> 79 | => DefaultProvider>.Instance.Generate(random, variants); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/StringUtilities.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Primitives 23 | { 24 | public static class StringUtilities 25 | { 26 | public static string[] ParseVectorParts(string value) 27 | { 28 | value = value.Trim(); 29 | 30 | if (value.StartsWith("(", StringComparison.InvariantCultureIgnoreCase) && 31 | value.EndsWith(")", StringComparison.InvariantCultureIgnoreCase)) 32 | value = value.Substring(1, value.Length - 2); 33 | 34 | if (value.StartsWith("[", StringComparison.InvariantCultureIgnoreCase) && 35 | value.EndsWith("]", StringComparison.InvariantCultureIgnoreCase)) 36 | value = value.Substring(1, value.Length - 2); 37 | 38 | if (value.StartsWith("{", StringComparison.InvariantCultureIgnoreCase) && 39 | value.EndsWith("}", StringComparison.InvariantCultureIgnoreCase)) 40 | value = value.Substring(1, value.Length - 2); 41 | 42 | if (value.StartsWith("<", StringComparison.InvariantCultureIgnoreCase) && 43 | value.EndsWith(">", StringComparison.InvariantCultureIgnoreCase)) 44 | value = value.Substring(1, value.Length - 2); 45 | 46 | string[] parts = value.Split(','); 47 | if (parts.Length == 1) parts = value.Split('|'); 48 | if (parts.Length == 1) parts = value.Split('\t'); 49 | 50 | return parts; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/TAGS.md: -------------------------------------------------------------------------------- 1 | primitive, primitives, utility, utilities, compatibility, shim, shims, jodo, jodosoft -------------------------------------------------------------------------------- /src/Jodosoft.Primitives/Variants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Primitives 23 | { 24 | /// 25 | /// Specifies categories for the random generation of objects. The exact definition 26 | /// of each category is left to the implementor. 27 | /// 28 | /// 29 | /// 30 | [Flags] 31 | public enum Variants : byte 32 | { 33 | /// 34 | /// Does not specify a category for random generation. The behavior of implementations is undefined. 35 | /// 36 | None = 0, 37 | 38 | /// 39 | /// Includes null, zero, and any other default state for a given object. 40 | /// 41 | Defaults = 1, 42 | 43 | /// 44 | /// Includes small values and values with reduced significance. 45 | /// 46 | LowMagnitude = 2, 47 | 48 | /// 49 | /// Includes any value from the set of all possible values, excluding errors. 50 | /// 51 | AnyMagnitude = 4, 52 | 53 | /// 54 | /// Includes minimum and maximum values. 55 | /// 56 | Boundaries = 8, 57 | 58 | /// 59 | /// Includes values that are typical of error scenarios, or values intended to elicit errors. 60 | /// 61 | Errors = 16, 62 | 63 | /// 64 | /// Encompasses all variants. 65 | /// 66 | All = Defaults | LowMagnitude | AnyMagnitude | Boundaries | Errors, 67 | 68 | /// 69 | /// Encompasses all variants, except for errors. 70 | /// 71 | NonError = Defaults | LowMagnitude | AnyMagnitude | Boundaries, 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing.NewtonsoftJson/Jodosoft.Testing.NewtonsoftJson.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | False 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing.NewtonsoftJson/JsonConvertTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using FluentAssertions; 22 | using Jodosoft.Primitives; 23 | using Newtonsoft.Json; 24 | using NUnit.Framework; 25 | 26 | namespace Jodosoft.Testing.NewtonsoftJson 27 | { 28 | public abstract class JsonConvertTestBase : GlobalFixtureBase where T : struct, IProvider> 29 | { 30 | [Test, Repeat(RandomVariations)] 31 | public void SerializeObject_RandomVariantFromJson_CanRoundTrip() 32 | { 33 | //arrange 34 | T input = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(Random.NextVariant(Variants.LowMagnitude))); 35 | 36 | //act 37 | T result = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(input)); 38 | 39 | //assert 40 | result.Should().Be(input); 41 | } 42 | 43 | [Test, Repeat(RandomVariations)] 44 | public void SerializeObjectInList_RandomVariantsFromJson_CanRoundTrip() 45 | { 46 | //arrange 47 | T[] inputs = new T[] { 48 | JsonConvert.DeserializeObject(JsonConvert.SerializeObject(Random.NextVariant(Variants.LowMagnitude))), 49 | JsonConvert.DeserializeObject(JsonConvert.SerializeObject(Random.NextVariant(Variants.LowMagnitude))), 50 | JsonConvert.DeserializeObject(JsonConvert.SerializeObject(Random.NextVariant(Variants.LowMagnitude))) 51 | }; 52 | 53 | //act 54 | T[] results = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(inputs)); 55 | 56 | //assert 57 | results.Should().BeEquivalentTo(inputs); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing.Tests/Jodosoft.Testing.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing/AssertionMethodAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | 22 | namespace Jodosoft.Testing 23 | { 24 | /// 25 | /// This attribute marks methods used to make assertions. This is used by static 26 | /// analysis tools to validate that test methods contain assertions. 27 | /// 28 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] 29 | public class AssertionMethodAttribute : Attribute { } 30 | } 31 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing/FixtureExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Linq; 21 | using System.Reflection; 22 | using AutoFixture; 23 | using AutoFixture.Kernel; 24 | 25 | namespace Jodosoft.Testing 26 | { 27 | public static class FixtureExtensions 28 | { 29 | public static object[] MockParameters(this Fixture fixture, MethodInfo methodInfo) => 30 | methodInfo.GetParameters() 31 | .Select(p => new SpecimenContext(fixture).Resolve(p.ParameterType)) 32 | .ToArray(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing/FormattableTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using System.Globalization; 22 | using System.Linq; 23 | using FluentAssertions; 24 | using Jodosoft.Primitives; 25 | using NUnit.Framework; 26 | 27 | namespace Jodosoft.Testing 28 | { 29 | /// 30 | /// Provides common test methods for structs that verify fundamental methods such 31 | /// as and . 32 | /// 33 | /// The type of struct. 34 | public abstract class FormattableTestBase : GlobalFixtureBase where T : struct, IFormattable, IProvider> 35 | { 36 | [Test, Repeat(RandomVariations)] 37 | public void ToString_MultipleInvocationsWithNullFormat_ReturnsSameValue() 38 | { 39 | //arrange 40 | T input = Random.NextVariant(); 41 | 42 | string[] results = new string[100]; 43 | 44 | //act 45 | for (int i = 0; i < results.Length; i++) 46 | { 47 | results[i] = input.ToString(null, null); 48 | } 49 | 50 | //assert 51 | results.Distinct().Should().HaveCount(1); 52 | } 53 | 54 | [Test, Repeat(RandomVariations)] 55 | public void ToString_RandomInputsWithNullFormat_ReturnsDifferentValues() 56 | { 57 | //arrange 58 | string[] results = new string[100]; 59 | 60 | //act 61 | for (int i = 0; i < results.Length; i++) 62 | { 63 | T input = Random.NextVariant(); 64 | 65 | results[i] = input.ToString(null, null); 66 | } 67 | 68 | //assert 69 | results.Distinct().Should().HaveCountGreaterThan(1); 70 | } 71 | 72 | [Test, Repeat(RandomVariations)] 73 | public void ToString_RandomInputWithNullFormat_SameAsToString() 74 | { 75 | //arrange 76 | T input = Random.NextVariant(); 77 | 78 | //act 79 | string result = input.ToString(null, null); 80 | 81 | //assert 82 | result.Should().Be(result.ToString()); 83 | } 84 | 85 | [Test, Repeat(RandomVariations)] 86 | public void ToString_RandomInputWithCurrentCulture_SameAsToString() 87 | { 88 | //arrange 89 | T input = Random.NextVariant(); 90 | 91 | //act 92 | string result = input.ToString(null, CultureInfo.CurrentCulture); 93 | 94 | //assert 95 | result.Should().Be(result.ToString()); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing/GlobalFixtureBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using NUnit.Framework; 22 | 23 | namespace Jodosoft.Testing 24 | { 25 | [Parallelizable(ParallelScope.Children)] 26 | [Timeout(10000)] 27 | public abstract class GlobalFixtureBase 28 | { 29 | #if DEBUG 30 | public const int RandomVariations = 16; 31 | #else 32 | public const int RandomVariations = 256; 33 | #endif 34 | 35 | public static Random Random => TestLocal.GetOrAdd(() => new Random()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing/Jodosoft.Testing.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | False 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing/SerializableTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Diagnostics.CodeAnalysis; 21 | using System.IO; 22 | using System.Runtime.Serialization; 23 | using System.Runtime.Serialization.Formatters.Binary; 24 | using FluentAssertions; 25 | using Jodosoft.Primitives; 26 | using NUnit.Framework; 27 | 28 | namespace Jodosoft.Testing 29 | { 30 | /// 31 | /// Provides common test methods for structs that implement . 32 | /// 33 | /// The type that implements . 34 | [SuppressMessage("csharpsquid", "S5773:Restrict types of objects allowed to be deserialized.", Justification = "Left unrestricted for testing purposes only.")] 35 | public abstract class SerializableTestBase : GlobalFixtureBase where T : struct, ISerializable, IProvider> 36 | { 37 | [Test, Repeat(RandomVariations)] 38 | public void Serialize_RoundTrip_SameAsOriginal() 39 | { 40 | //arrange 41 | T input = Random.NextVariant(Variants.NonError); 42 | BinaryFormatter formatter = new BinaryFormatter(); 43 | 44 | //act 45 | T result; 46 | using (MemoryStream stream = new MemoryStream()) 47 | { 48 | #pragma warning disable IDE0079 // Remove unnecessary suppression - Justification: Warning below not raised in all target frameworks 49 | #pragma warning disable SYSLIB0011 // Type or member is obsolete - Justification: For test 50 | formatter.Serialize(stream, input); 51 | stream.Position = 0; 52 | result = (T)formatter.Deserialize(stream); 53 | #pragma warning restore SYSLIB0011 // Type or member is obsolete 54 | #pragma warning restore IDE0079 // Remove unnecessary suppression 55 | } 56 | 57 | //assert 58 | result.Should().Be(input); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Jodosoft.Testing/TestLocal.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System; 21 | using NUnit.Framework.Interfaces; 22 | using NUnit.Framework.Internal; 23 | 24 | namespace Jodosoft.Testing 25 | { 26 | /// 27 | /// Provides test-local storage of data. 28 | /// 29 | public static class TestLocal 30 | { 31 | public static T GetOrAdd(Func factory) 32 | { 33 | IPropertyBag propertyBag = (TestExecutionContext.CurrentContext?.CurrentTest?.Properties) 34 | ?? throw new InvalidOperationException("Test context not found."); 35 | string key = $"{nameof(TestLocal)}+{typeof(T).Name}"; 36 | if (!propertyBag.ContainsKey(key)) 37 | { 38 | propertyBag.Set(key, factory()); 39 | } 40 | return (T)propertyBag.Get(key); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/PackageIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jodosoft/Libraries/7c1e73eacaace8374bd8e6b99f50817da22708ba/src/PackageIcon.png -------------------------------------------------------------------------------- /src/Packages.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2.0.0.0 4 | 2.0.0 5 | 2.0.0 6 | preview1 7 | False 8 | true 9 | 10 | 11 | 12 | netstandard2.1;netstandard2.0;net461 13 | true 14 | portable 15 | enable 16 | 17 | 18 | 19 | 20 | 21 | $(NoWarn);CS1591; 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | $(MSBuildProjectName) 37 | $(MSBuildProjectName) 38 | Joe Lawry-Short 39 | Joe Lawry-Short 40 | true 41 | Copyright © Joe Lawry-Short 2023 42 | $(DefaultItemExcludes);bin\** 43 | $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)\README.md")) 44 | true 45 | true 46 | true 47 | true 48 | true 49 | true 50 | en-GB 51 | true 52 | PackageIcon.png 53 | $(MSBuildProjectName) 54 | MIT 55 | https://github.com/Jodosoft/Libraries 56 | README.md 57 | https://github.com/Jodosoft/Libraries/#changelog 58 | $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)\TAGS.md")) 59 | true 60 | The Jodosoft Libraries 61 | true 62 | git 63 | https://github.com/Jodosoft/Libraries.git 64 | $(MSBuildProjectName) 65 | snupkg 66 | $(MSBuildProjectName) 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/PackagesNonBreaking.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/TestAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Joe Lawry-Short 2 | // Permission is hereby granted, free of charge, to any person obtaining a copy 3 | // of this software and associated documentation files (the "Software"), to 4 | // deal in the Software without restriction, including without limitation the 5 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 | // sell copies of the Software, and to permit persons to whom the Software is 7 | // furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in 10 | // all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | using System.Diagnostics.CodeAnalysis; 21 | 22 | [assembly: SuppressMessage("Style", "IDE0058:Expression value is never used", Justification = "Fluent assertions")] 23 | [assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Subject_When_Then naming convention for test methods")] 24 | [assembly: SuppressMessage("CodeQuality", "IDE0079:Remove unnecessary suppression", MessageId = "csharpsquid", Justification = "False positive on csharpsquid suppressions")] 25 | -------------------------------------------------------------------------------- /src/Tests.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net7.0;net6.0;netcoreapp2.1;net48 4 | false 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | --------------------------------------------------------------------------------