diff --git a/QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs b/QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs index 0c9fb36..64f9dc2 100644 --- a/QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs +++ b/QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs @@ -1254,15 +1254,6 @@ public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, I public static class {typeNameZ}Extensions { - internal static double Protected(this {typeNameZ}? unit) => unit is null ? 0d : unit.Value._Value; - internal static {typeNameZ} ProtectedU(this {typeNameZ}? unit) => unit is null ? {typeNameZ}.Zero : unit.Value; - internal static double ToDouble(this {typeNameB}? unit) => unit?._Value ?? 0d; - - - - - - // === ReadOnlySpan [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ReadOnlySpan<{typeNameZ}> units, double divisor, Span<{typeNameZ}> destination) => units.Div<{typeNameZ}>(divisor, destination); diff --git a/QWERTYkez.Mensura.Generator/UnitGenerator.cs b/QWERTYkez.Mensura.Generator/UnitGenerator.cs index 5729f05..b00be52 100644 --- a/QWERTYkez.Mensura.Generator/UnitGenerator.cs +++ b/QWERTYkez.Mensura.Generator/UnitGenerator.cs @@ -1073,14 +1073,6 @@ public readonly partial record struct {typeName} : IMensuraUnit<{typeName}>, IEq public static class {typeName}Extensions { - internal static double Protected(this {typeName}? unit) => unit is null ? 0d : unit.Value._Value; - internal static {typeName} ProtectedU(this {typeName}? unit) => unit is null ? {typeName}.Zero : unit.Value; - - - - - - // === ReadOnlySpan [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ReadOnlySpan<{typeName}> units, double divisor, Span<{typeName}> destination) => units.Div<{typeName}>(divisor, destination); diff --git a/QWERTYkez.Mensura.Tests/AggregateUnitExtensions.cs b/QWERTYkez.Mensura.Tests/AggregateUnitExtensionsTest.cs similarity index 99% rename from QWERTYkez.Mensura.Tests/AggregateUnitExtensions.cs rename to QWERTYkez.Mensura.Tests/AggregateUnitExtensionsTest.cs index c16e34e..5b3757a 100644 --- a/QWERTYkez.Mensura.Tests/AggregateUnitExtensions.cs +++ b/QWERTYkez.Mensura.Tests/AggregateUnitExtensionsTest.cs @@ -2,7 +2,7 @@ namespace QWERTYkez.Mensura.Tests; -public class AggregateUnitExtensions +public class AggregateUnitExtensionsTest { // Вспомогательный метод для создания объекта Length. // Если у вас используется фабричный метод (например, Length.FromMeters), замените код внутри. diff --git a/QWERTYkez.Mensura.Tests/CastExtensions.cs b/QWERTYkez.Mensura.Tests/CastExtensionsTest.cs similarity index 99% rename from QWERTYkez.Mensura.Tests/CastExtensions.cs rename to QWERTYkez.Mensura.Tests/CastExtensionsTest.cs index 3f72b33..d2bb5d0 100644 --- a/QWERTYkez.Mensura.Tests/CastExtensions.cs +++ b/QWERTYkez.Mensura.Tests/CastExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests; -public class CastExtensions +public class CastExtensionsTest { private const double NormalValue1 = 42.42; private const double NormalValue2 = 100.05; diff --git a/QWERTYkez.Mensura.Tests/CollectionsDivideExtensions.cs b/QWERTYkez.Mensura.Tests/CollectionsDivideExtensionsTest.cs similarity index 93% rename from QWERTYkez.Mensura.Tests/CollectionsDivideExtensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsDivideExtensionsTest.cs index f543f95..f1a41e1 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsDivideExtensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsDivideExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests { - public class CollectionsDivideExtensionsTests + public class CollectionsDivideExtensionsTest { private const double Tolerance = 1e-12; private static readonly Length scalarUnit = Length.Meter; // 1000 mm @@ -31,7 +31,7 @@ var result = nullableUnitsArray.Div(scalarDouble); Assert.Equal(3, result.Length); Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 / 2.0, (double)result[1]!, Tolerance); Assert.Equal(1 / 2.0, (double)result[2]!, Tolerance); } @@ -52,7 +52,7 @@ var result = scalarDouble.Div(nullableUnitsArray); Assert.Equal(3, result.Length); Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(2.0 / 0, (double)result[1]!, Tolerance); Assert.Equal(2.0 / 1, (double)result[2]!, Tolerance); } @@ -73,7 +73,7 @@ var result = nullableUnitsList.Div(scalarDouble); Assert.Equal(3, result.Count); Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 / 2.0, (double)result[1]!, Tolerance); Assert.Equal(1 / 2.0, (double)result[2]!, Tolerance); } @@ -94,7 +94,7 @@ var result = scalarDouble.Div(nullableUnitsList); Assert.Equal(3, result.Count); Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(2.0 / 0, (double)result[1]!, Tolerance); Assert.Equal(2.0 / 1, (double)result[2]!, Tolerance); } @@ -115,7 +115,7 @@ Span dest = new Length?[3]; ((IReadOnlyCollection)nullableUnitsArray).Div(scalarDouble, dest); Assert.Equal(1000 / 2.0, (double)dest[0]!, Tolerance); - Assert.Null(dest[1]); + Assert.Equal(0 / 2.0, (double)dest[1]!, Tolerance); Assert.Equal(1 / 2.0, (double)dest[2]!, Tolerance); } @@ -136,7 +136,7 @@ Span dest = new Length?[3]; scalarDouble.Div((IReadOnlyCollection)nullableUnitsArray, dest); Assert.Equal(2.0 / 1000, (double)dest[0]!, Tolerance); - Assert.Null(dest[1]); + Assert.Equal(2.0 / 0, (double)dest[1]!, Tolerance); Assert.Equal(2.0 / 1, (double)dest[2]!, Tolerance); } @@ -157,7 +157,7 @@ var result = ((IEnumerable)nullableUnitsArray).Div(scalarDouble).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 / 2.0, (double)result[1]!, Tolerance); Assert.Equal(1 / 2.0, (double)result[2]!, Tolerance); } @@ -178,7 +178,7 @@ var result = scalarDouble.Div((IEnumerable)nullableUnitsArray).ToList(); Assert.Equal(3, result.Count); Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(2.0 / 0, (double)result[1]!, Tolerance); Assert.Equal(2.0 / 1, (double)result[2]!, Tolerance); } @@ -199,7 +199,7 @@ var result = nullableDoubleArray.Div(scalarUnit); Assert.Equal(3, result.Length); Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 / 1000, (double)result[1]!, Tolerance); Assert.Equal(3.0 / 1000, (double)result[2]!, Tolerance); } @@ -220,7 +220,7 @@ var result = scalarUnit.Div(nullableDoubleArray); Assert.Equal(3, result.Length); Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(1000 / 0.0, (double)result[1]!, Tolerance); Assert.Equal(1000 / 3.0, (double)result[2]!, Tolerance); } @@ -243,7 +243,7 @@ var result = list.Div(scalarUnit); Assert.Equal(3, result.Count); Assert.Equal(2.0 / 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 / 1000, (double)result[1]!, Tolerance); Assert.Equal(3.0 / 1000, (double)result[2]!, Tolerance); } @@ -266,7 +266,7 @@ var result = scalarUnit.Div(list); Assert.Equal(3, result.Count); Assert.Equal(1000 / 2.0, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(1000 / 0.0, (double)result[1]!, Tolerance); Assert.Equal(1000 / 3.0, (double)result[2]!, Tolerance); } diff --git a/QWERTYkez.Mensura.Tests/CollectionsMinusExtensions.cs b/QWERTYkez.Mensura.Tests/CollectionsMinusExtensionsTest.cs similarity index 94% rename from QWERTYkez.Mensura.Tests/CollectionsMinusExtensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsMinusExtensionsTest.cs index ebaf4d1..c4cb061 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsMinusExtensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsMinusExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests { - public class CollectionsMinusExtensionsTests + public class CollectionsMinusExtensionsTest { private const double Tolerance = 1e-12; private static readonly Length scalarUnit = Length.Meter; // 1000 mm @@ -44,7 +44,7 @@ var result = nullableUnitsArray.Minus(scalarDouble); Assert.Equal(3, result.Length); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(1 - 1000, (double)result[2]!, Tolerance); } @@ -65,7 +65,7 @@ var result = scalarDouble.Minus(nullableUnitsArray); Assert.Equal(3, result.Length); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 1, (double)result[2]!, Tolerance); } @@ -86,7 +86,7 @@ var result = nullableUnitsList.Minus(scalarDouble); Assert.Equal(3, result.Count); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(1 - 1000, (double)result[2]!, Tolerance); } @@ -107,7 +107,7 @@ var result = scalarDouble.Minus(nullableUnitsList); Assert.Equal(3, result.Count); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 1, (double)result[2]!, Tolerance); } @@ -128,7 +128,7 @@ Span dest = new Length?[3]; ((IReadOnlyCollection)nullableUnitsArray).Minus(scalarDouble, dest); Assert.Equal(1000 - 1000, (double)dest[0]!, Tolerance); - Assert.Null(dest[1]); + Assert.Equal(0 - 1000, (double)dest[1]!, Tolerance); Assert.Equal(1 - 1000, (double)dest[2]!, Tolerance); } @@ -149,7 +149,7 @@ Span dest = new Length?[3]; scalarDouble.Minus((IReadOnlyCollection)nullableUnitsArray, dest); Assert.Equal(1000 - 1000, (double)dest[0]!, Tolerance); - Assert.Null(dest[1]); + Assert.Equal(1000 - 0, (double)dest[1]!, Tolerance); Assert.Equal(1000 - 1, (double)dest[2]!, Tolerance); } @@ -170,7 +170,7 @@ var result = ((IEnumerable)nullableUnitsArray).Minus(scalarDouble).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(1 - 1000, (double)result[2]!, Tolerance); } @@ -191,7 +191,7 @@ var result = scalarDouble.Minus((IEnumerable)nullableUnitsArray).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 - 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 1, (double)result[2]!, Tolerance); } @@ -212,7 +212,7 @@ var result = nullableDoubleArray.Minus(scalarUnit); Assert.Equal(3, result.Length); Assert.Equal(500 - 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(200 - 1000, (double)result[2]!, Tolerance); } @@ -233,7 +233,7 @@ var result = scalarUnit.Minus(nullableDoubleArray); Assert.Equal(3, result.Length); Assert.Equal(1000 - 500, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 200, (double)result[2]!, Tolerance); } @@ -254,7 +254,7 @@ var result = nullableDoubleList.Minus(scalarUnit); Assert.Equal(3, result.Count); Assert.Equal(500 - 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(0 - 1000, (double)result[1]!, Tolerance); Assert.Equal(200 - 1000, (double)result[2]!, Tolerance); } @@ -275,7 +275,7 @@ var result = scalarUnit.Minus(nullableDoubleList); Assert.Equal(3, result.Count); Assert.Equal(1000 - 500, (double)result[0]!, Tolerance); - Assert.Null(result[1]); + Assert.Equal(1000 - 0, (double)result[1]!, Tolerance); Assert.Equal(1000 - 200, (double)result[2]!, Tolerance); } diff --git a/QWERTYkez.Mensura.Tests/CollectionsMultiplyExtensions.cs b/QWERTYkez.Mensura.Tests/CollectionsMultiplyExtensionsTest.cs similarity index 93% rename from QWERTYkez.Mensura.Tests/CollectionsMultiplyExtensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsMultiplyExtensionsTest.cs index 157b631..41f485f 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsMultiplyExtensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsMultiplyExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests { - public class CollectionsMultiplyExtensionsTests + public class CollectionsMultiplyExtensionsTest { private const double Tolerance = 1e-12; private static readonly Length scalarUnit = Length.Meter; // 1000 mm @@ -43,7 +43,7 @@ var result = nullableUnitsArray.Mul(scalarDouble); Assert.Equal(3, result.Length); Assert.Equal(1000 * 2, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null * 2 = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1 * 2, (double)result[2]!, Tolerance); } @@ -64,7 +64,7 @@ var result = scalarDouble.Mul(nullableUnitsArray); Assert.Equal(3, result.Length); Assert.Equal(2 * 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // 2 * null = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(2 * 1, (double)result[2]!, Tolerance); } @@ -85,7 +85,7 @@ var result = nullableUnitsList.Mul(scalarDouble); Assert.Equal(3, result.Count); Assert.Equal(1000 * 2, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null * 2 = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1 * 2, (double)result[2]!, Tolerance); } @@ -106,7 +106,7 @@ var result = scalarDouble.Mul(nullableUnitsList); Assert.Equal(3, result.Count); Assert.Equal(2 * 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // 2 * null = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(2 * 1, (double)result[2]!, Tolerance); } @@ -127,7 +127,7 @@ Span dest = new Length?[3]; ((IReadOnlyCollection)nullableUnitsArray).Mul(scalarDouble, dest); Assert.Equal(1000 * 2, (double)dest[0]!, Tolerance); - Assert.Null(dest[1]); // null * 2 = null + Assert.Equal(0, (double)dest[1]!, Tolerance); Assert.Equal(1 * 2, (double)dest[2]!, Tolerance); } @@ -148,7 +148,7 @@ Span dest = new Length?[3]; scalarDouble.Mul((IReadOnlyCollection)nullableUnitsArray, dest); Assert.Equal(2 * 1000, (double)dest[0]!, Tolerance); - Assert.Null(dest[1]); // 2 * null = null + Assert.Equal(0, (double)dest[1]!, Tolerance); Assert.Equal(2 * 1, (double)dest[2]!, Tolerance); } @@ -169,7 +169,7 @@ var result = ((IEnumerable)nullableUnitsArray).Mul(scalarDouble).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 * 2, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null * 2 = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1 * 2, (double)result[2]!, Tolerance); } @@ -190,7 +190,7 @@ var result = scalarDouble.Mul((IEnumerable)nullableUnitsArray).ToList(); Assert.Equal(3, result.Count); Assert.Equal(2 * 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // 2 * null = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(2 * 1, (double)result[2]!, Tolerance); } @@ -211,7 +211,7 @@ var result = nullableDoubleArray.Mul(scalarUnit); Assert.Equal(3, result.Length); Assert.Equal(5 * 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null * Length = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(3 * 1000, (double)result[2]!, Tolerance); } @@ -232,7 +232,7 @@ var result = scalarUnit.Mul(nullableDoubleArray); Assert.Equal(3, result.Length); Assert.Equal(1000 * 5, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // Length * null = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1000 * 3, (double)result[2]!, Tolerance); } @@ -253,7 +253,7 @@ var result = nullableDoubleList.Mul(scalarUnit); Assert.Equal(3, result.Count); Assert.Equal(5 * 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null * Length = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(3 * 1000, (double)result[2]!, Tolerance); } @@ -274,7 +274,7 @@ var result = scalarUnit.Mul(nullableDoubleList); Assert.Equal(3, result.Count); Assert.Equal(1000 * 5, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // Length * null = null + Assert.Equal(0, (double)result[1]!, Tolerance); Assert.Equal(1000 * 3, (double)result[2]!, Tolerance); } diff --git a/QWERTYkez.Mensura.Tests/CollectionsPlusExtensions.cs b/QWERTYkez.Mensura.Tests/CollectionsPlusExtensionsTest.cs similarity index 91% rename from QWERTYkez.Mensura.Tests/CollectionsPlusExtensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsPlusExtensionsTest.cs index 845e634..3154c08 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsPlusExtensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsPlusExtensionsTest.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using QWERTYkez.Mensura.Units; -using QWERTYkez.Mensura.Extensions; -using Xunit; - -namespace QWERTYkez.Mensura.Tests +namespace QWERTYkez.Mensura.Tests { - public class CollectionsPlusExtensionsTests + public class CollectionsPlusExtensionsTest { private const double Tolerance = 1e-12; private static readonly Length scalarUnit = Length.Meter; // 1000 mm @@ -42,7 +35,7 @@ namespace QWERTYkez.Mensura.Tests var result = nullableUnitsArray.Plus(scalarDouble); Assert.Equal(3, result.Length); Assert.Equal(1000 + 500, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null + число = null + Assert.Equal(0 + 500, (double)result[1]!, Tolerance); Assert.Equal(1 + 500, (double)result[2]!, Tolerance); } @@ -63,7 +56,7 @@ namespace QWERTYkez.Mensura.Tests var result = scalarDouble.Plus(nullableUnitsArray); Assert.Equal(3, result.Length); Assert.Equal(500 + 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // число + null = null + Assert.Equal(500 + 0, (double)result[1]!, Tolerance); Assert.Equal(500 + 1, (double)result[2]!, Tolerance); } @@ -84,7 +77,7 @@ namespace QWERTYkez.Mensura.Tests var result = nullableUnitsList.Plus(scalarDouble); Assert.Equal(3, result.Count); Assert.Equal(1000 + 500, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null + число = null + Assert.Equal(0 + 500, (double)result[1]!, Tolerance); Assert.Equal(1 + 500, (double)result[2]!, Tolerance); } @@ -105,7 +98,7 @@ namespace QWERTYkez.Mensura.Tests var result = scalarDouble.Plus(nullableUnitsList); Assert.Equal(3, result.Count); Assert.Equal(500 + 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // число + null = null + Assert.Equal(500 + 0, (double)result[1]!, Tolerance); Assert.Equal(500 + 1, (double)result[2]!, Tolerance); } @@ -126,7 +119,7 @@ namespace QWERTYkez.Mensura.Tests Span dest = new Length?[3]; ((IReadOnlyCollection)nullableUnitsArray).Plus(scalarDouble, dest); Assert.Equal(1000 + 500, (double)dest[0]!, Tolerance); - Assert.Null(dest[1]); // null + число = null + Assert.Equal(0 + 500, (double)dest[1]!, Tolerance); Assert.Equal(1 + 500, (double)dest[2]!, Tolerance); } @@ -147,7 +140,7 @@ namespace QWERTYkez.Mensura.Tests Span dest = new Length?[3]; scalarDouble.Plus((IReadOnlyCollection)nullableUnitsArray, dest); Assert.Equal(500 + 1000, (double)dest[0]!, Tolerance); - Assert.Null(dest[1]); // число + null = null + Assert.Equal(500 + 0, (double)dest[1]!, Tolerance); Assert.Equal(500 + 1, (double)dest[2]!, Tolerance); } @@ -168,7 +161,7 @@ namespace QWERTYkez.Mensura.Tests var result = ((IEnumerable)nullableUnitsArray).Plus(scalarDouble).ToList(); Assert.Equal(3, result.Count); Assert.Equal(1000 + 500, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null + число = null + Assert.Equal(0 + 500, (double)result[1]!, Tolerance); Assert.Equal(1 + 500, (double)result[2]!, Tolerance); } @@ -189,7 +182,7 @@ namespace QWERTYkez.Mensura.Tests var result = scalarDouble.Plus((IEnumerable)nullableUnitsArray).ToList(); Assert.Equal(3, result.Count); Assert.Equal(500 + 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // число + null = null + Assert.Equal(500 + 0, (double)result[1]!, Tolerance); Assert.Equal(500 + 1, (double)result[2]!, Tolerance); } @@ -210,7 +203,7 @@ namespace QWERTYkez.Mensura.Tests var result = nullableDoubleArray.Plus(scalarUnit); Assert.Equal(3, result.Length); Assert.Equal(200 + 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null + Length = null + Assert.Equal(0 + 1000, (double)result[1]!, Tolerance); Assert.Equal(300 + 1000, (double)result[2]!, Tolerance); } @@ -231,7 +224,7 @@ namespace QWERTYkez.Mensura.Tests var result = scalarUnit.Plus(nullableDoubleArray); Assert.Equal(3, result.Length); Assert.Equal(1000 + 200, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // Length + null = null + Assert.Equal(1000 + 0, (double)result[1]!, Tolerance); Assert.Equal(1000 + 300, (double)result[2]!, Tolerance); } @@ -252,7 +245,7 @@ namespace QWERTYkez.Mensura.Tests var result = nullableDoubleList.Plus(scalarUnit); Assert.Equal(3, result.Count); Assert.Equal(200 + 1000, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // null + Length = null + Assert.Equal(0 + 1000, (double)result[1]!, Tolerance); Assert.Equal(300 + 1000, (double)result[2]!, Tolerance); } @@ -273,7 +266,7 @@ namespace QWERTYkez.Mensura.Tests var result = scalarUnit.Plus(nullableDoubleList); Assert.Equal(3, result.Count); Assert.Equal(1000 + 200, (double)result[0]!, Tolerance); - Assert.Null(result[1]); // Length + null = null + Assert.Equal(1000 + 0, (double)result[1]!, Tolerance); Assert.Equal(1000 + 300, (double)result[2]!, Tolerance); } diff --git a/QWERTYkez.Mensura.Tests/CollectionsPow2Extensions.cs b/QWERTYkez.Mensura.Tests/CollectionsPow2ExtensionsTest.cs similarity index 97% rename from QWERTYkez.Mensura.Tests/CollectionsPow2Extensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsPow2ExtensionsTest.cs index 80c8715..43fe5fb 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsPow2Extensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsPow2ExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests; -public class CollectionsPow2Extensions +public class CollectionsPow2ExtensionsTest { [Fact] public void Pow2_Array_CalculatesCorrectly() diff --git a/QWERTYkez.Mensura.Tests/CollectionsPow3Extensions.cs b/QWERTYkez.Mensura.Tests/CollectionsPow3ExtensionsTest.cs similarity index 97% rename from QWERTYkez.Mensura.Tests/CollectionsPow3Extensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsPow3ExtensionsTest.cs index ebdfa8c..030f290 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsPow3Extensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsPow3ExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests; -public class Pow3ExtensionsTests +public class CollectionsPow3ExtensionsTest { [Fact] public void Pow3_Array_CalculatesCorrectly() diff --git a/QWERTYkez.Mensura.Tests/CollectionsPowNExtensions.cs b/QWERTYkez.Mensura.Tests/CollectionsPowNExtensionsTest.cs similarity index 98% rename from QWERTYkez.Mensura.Tests/CollectionsPowNExtensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsPowNExtensionsTest.cs index cccc304..f31ac16 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsPowNExtensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsPowNExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests; -public class CollectionsPowNExtensions +public class CollectionsPowNExtensionsTest { private const double BaseVal = 3.0; private const double Expected = 9.0; // 3^2 = 9 diff --git a/QWERTYkez.Mensura.Tests/CollectionsRootOfCubeExtensions.cs b/QWERTYkez.Mensura.Tests/CollectionsRootOfCubeExtensionsTest.cs similarity index 94% rename from QWERTYkez.Mensura.Tests/CollectionsRootOfCubeExtensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsRootOfCubeExtensionsTest.cs index f03a73e..de460a9 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsRootOfCubeExtensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsRootOfCubeExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests; -public class CollectionsRootOfCubeExtensions +public class CollectionsRootOfCubeExtensionsTest { [Fact] public void Cbrt_Array_CalculatesCorrectly() @@ -23,7 +23,7 @@ public class CollectionsRootOfCubeExtensions var result = source.Cbrt(); Assert.Equal(4, result[0]?._Value); - Assert.Null(result[1]); + Assert.Equal(0, result[1]?._Value); Assert.Equal(6, result[2]?._Value); } diff --git a/QWERTYkez.Mensura.Tests/CollectionsRootOfSquareExtensions.cs b/QWERTYkez.Mensura.Tests/CollectionsRootOfSquareExtensionsTest.cs similarity index 95% rename from QWERTYkez.Mensura.Tests/CollectionsRootOfSquareExtensions.cs rename to QWERTYkez.Mensura.Tests/CollectionsRootOfSquareExtensionsTest.cs index 2d91013..4129b46 100644 --- a/QWERTYkez.Mensura.Tests/CollectionsRootOfSquareExtensions.cs +++ b/QWERTYkez.Mensura.Tests/CollectionsRootOfSquareExtensionsTest.cs @@ -1,6 +1,6 @@ namespace QWERTYkez.Mensura.Tests; -public class CollectionsRootOfSquareExtensions +public class CollectionsRootOfSquareExtensionsTest { [Fact] public void Sqrt_Array_ShouldCalculateCorrectly() @@ -28,7 +28,7 @@ public class CollectionsRootOfSquareExtensions // Assert Assert.Equal(5, result[0]?._Value); - Assert.Null(result[1]); + Assert.Equal(0, result[1]?._Value); Assert.Equal(10, result[2]?._Value); } diff --git a/QWERTYkez.Mensura.Tests/DoubleExtensions.cs b/QWERTYkez.Mensura.Tests/DoubleExtensions.cs deleted file mode 100644 index 61abf51..0000000 --- a/QWERTYkez.Mensura.Tests/DoubleExtensions.cs +++ /dev/null @@ -1,164 +0,0 @@ -namespace QWERTYkez.Mensura.Tests; - -public class DoubleExtensions -{ - #region 1. Тесты скалярных типов (Обычные, Экзотические и Nullable) - - [Fact] - public void ToDouble_Should_Convert_ExoticTypes_Without_InvalidCastException() - { - // Проверяем типы, которые раньше могли падать в рантайме из-за Convert.ToDouble(object) - Half halfValue = (Half)3.14f; - Int128 int128Value = Int128.Parse("1234567890123456789012345"); - UInt128 uInt128Value = UInt128.Parse("9876543210987654321098765"); - nint nintValue = 42; - - // Act & Assert - Assert.Equal(3.14, halfValue.ToDouble(), 2); - Assert.Equal((double)int128Value, int128Value.ToDouble()); - Assert.Equal((double)uInt128Value, uInt128Value.ToDouble()); - Assert.Equal(42.0, nintValue.ToDouble()); - } - - [Theory] - [InlineData((int)100, 100.0)] - [InlineData((byte)5, 5.0)] - [InlineData((float)1.5f, 1.5)] - public void ToDouble_StandardScalars_ShouldConvertCorrectly(object input, double expected) - { - double result = input switch - { - int i => i.ToDouble(), - byte b => b.ToDouble(), - float f => f.ToDouble(), - _ => throw new ArgumentException("Unsupported type in test") - }; - - Assert.Equal(expected, result); - } - - [Fact] - public void ToDouble_NullableScalars_Should_Return_Zero_When_Null() - { - // Arrange - int? nullInt = null; - Half? nullHalf = null; - Int128? nullInt128 = null; - - int? validInt = 10; - Half? validHalf = (Half)2.5f; - - // Act & Assert - Assert.Equal(0d, nullInt.ToDouble()); - Assert.Equal(0d, nullHalf.ToDouble()); - Assert.Equal(0d, nullInt128.ToDouble()); - - Assert.Equal(10d, validInt.ToDouble()); - Assert.Equal(2.5d, validHalf.ToDouble(), 1); - } - #endregion - - #region 2. Тесты SIMD и оптимизаций коллекций (Различные длины массивов) - - [Theory] - [InlineData(0)] // Пустой массив - [InlineData(1)] // 1 элемент (чисто скалярный fallback) - [InlineData(7)] // Нечетное число элементов - [InlineData(16)] // Кратный размер (размер Vector128/Vector256) - [InlineData(35)] // Большой массив с остатком для скалярного хвоста - public void ToDouble_ArrayAndList_Should_Correctly_Map_Via_SIMD_Or_Fallback(int count) - { - // Arrange - float[] sourceArray = [.. Enumerable.Range(1, count).Select(x => x * 1.5f)]; - List sourceList = [.. sourceArray]; - - double[] destFromArray = new double[count]; - double[] destFromList = new double[count]; - - // Act - // Явное приведение к IReadOnlyCollection устраняет ошибку CS0121 (неоднозначность вызова) - ((IReadOnlyCollection)sourceArray).ToDouble(destFromArray); - ((IReadOnlyCollection)sourceList).ToDouble(destFromList); - - // Assert - for (int i = 0; i < count; i++) - { - double expected = sourceArray[i]; - Assert.Equal(expected, destFromArray[i]); - Assert.Equal(expected, destFromList[i]); - } - } - #endregion - - #region 3. Тесты Nullable-коллекций (Проверка на null-элементы внутри) - - [Fact] - public void ToDouble_Nullable_Collections_Should_Keep_Nulls_In_Destination() - { - // Arrange - UInt128?[] sourceArray = [10, null, 20, null, 30]; - double?[] destination = new double?[sourceArray.Length]; - - // Act - ((IReadOnlyCollection)sourceArray).ToDouble(destination); - - // Assert - Assert.Equal(10d, destination[0]); - Assert.Null(destination[1]); - Assert.Equal(20d, destination[2]); - Assert.Null(destination[3]); - Assert.Equal(30d, destination[4]); - } - #endregion - - #region 4. Тесты LINQ / Отложенного выполнения (IEnumerable) - - [Fact] - public void ToDouble_IEnumerable_Extension_Should_Handle_Execution_Types_Correctly() - { - // Arrange - int[] array = [1, 2, 3]; - List list = [4, 5, 6]; - IEnumerable genericEnum = Enumerable.Range(7, 3); - - // Act - var resFromArray = array.ToDouble(); // Быстрый бранч для массива - var resFromList = list.ToDouble(); // Быстрый бранч для списка - var resFromEnum = genericEnum.ToDouble(); // Медленный итератор по IEnumerable - - // Assert - Assert.Equal([1d, 2d, 3d], resFromArray); - Assert.Equal([4d, 5d, 6d], resFromList); - Assert.Equal([7d, 8d, 9d], resFromEnum); - } - #endregion - - #region 5. Тесты безопасности и валидации аргументов - - [Fact] - public void ToDouble_Should_Throw_ArgumentException_When_Destination_Is_Too_Short() - { - // Arrange - int[] source = [1, 2, 3, 4, 5]; - double[] destinationTooShort = new double[4]; // Нужен размер >= 5 - - // Act & Assert - Assert.Throws(() => ((IReadOnlyCollection)source).ToDouble(destinationTooShort)); - } - - [Fact] - public void ToDouble_Should_Do_Nothing_And_Return_When_Collection_Is_Empty_Or_Null() - { - // Arrange - int[]? nullArray = null; - int[] emptyArray = []; - double[] destination = new double[5]; - - // Act & Assert (Не должно выбрасывать NullReferenceException или ArgumentException) - ((IReadOnlyCollection?)nullArray)!.ToDouble(destination); - ((IReadOnlyCollection)emptyArray).ToDouble(destination); - - Assert.All(destination, x => Assert.Equal(0d, x)); // Назначение осталось нетронутым (все нули по умолчанию) - } - #endregion -} \ No newline at end of file diff --git a/QWERTYkez.Mensura.Tests/DoubleExtensionsTest.cs b/QWERTYkez.Mensura.Tests/DoubleExtensionsTest.cs new file mode 100644 index 0000000..a0be873 --- /dev/null +++ b/QWERTYkez.Mensura.Tests/DoubleExtensionsTest.cs @@ -0,0 +1,394 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using QWERTYkez.Mensura.Extensions; +using Xunit; + +namespace QWERTYkez.Mensura.Tests +{ + public class DoubleExtensionsTests + { + private const double Tolerance = 1e-12; + + #region Single value conversions (non-nullable) + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(255)] + public void ToDouble_Byte_ReturnsExpected(byte value) => Assert.Equal(value, value.ToDouble()); + + [Theory] + [InlineData(-128)] + [InlineData(0)] + [InlineData(127)] + public void ToDouble_SByte_ReturnsExpected(sbyte value) => Assert.Equal(value, value.ToDouble()); + + [Theory] + [InlineData(-32768)] + [InlineData(0)] + [InlineData(32767)] + public void ToDouble_Short_ReturnsExpected(short value) => Assert.Equal(value, value.ToDouble()); + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(65535)] + public void ToDouble_UShort_ReturnsExpected(ushort value) => Assert.Equal(value, value.ToDouble()); + + [Theory] + [InlineData(-2147483648)] + [InlineData(0)] + [InlineData(2147483647)] + public void ToDouble_Int_ReturnsExpected(int value) => Assert.Equal(value, value.ToDouble()); + + [Theory] + [InlineData(0U)] + [InlineData(1U)] + [InlineData(uint.MaxValue)] + public void ToDouble_UInt_ReturnsExpected(uint value) => Assert.Equal(value, value.ToDouble()); + + [Theory] + [InlineData(-9223372036854775808)] + [InlineData(0)] + [InlineData(9223372036854775807)] + public void ToDouble_Long_ReturnsExpected(long value) => Assert.Equal((double)value, value.ToDouble(), Tolerance); + + [Theory] + [InlineData(0UL)] + [InlineData(1UL)] + [InlineData(ulong.MaxValue)] + public void ToDouble_ULong_ReturnsExpected(ulong value) => Assert.Equal((double)value, value.ToDouble(), Tolerance); + + [Theory] + [InlineData(-123456789)] + [InlineData(0)] + [InlineData(123456789)] + public void ToDouble_NInt_ReturnsExpected(nint value) => Assert.Equal(value, value.ToDouble()); + + [Theory] + [InlineData(0u)] + [InlineData(123456789u)] + public void ToDouble_NUInt_ReturnsExpected(nuint value) => Assert.Equal((double)value, value.ToDouble()); + + [Theory] + [InlineData(0.0f)] + [InlineData(123.456f)] + [InlineData(-987.654f)] + [InlineData(float.Epsilon)] + [InlineData(float.MaxValue)] + public void ToDouble_Float_ReturnsExpected(float value) => Assert.Equal((double)value, value.ToDouble(), Tolerance); + + [Theory] + [InlineData(0.0)] + [InlineData(123.456)] + [InlineData(-987.654)] + public void ToDouble_Decimal_ReturnsExpected(decimal value) => Assert.Equal((double)value, value.ToDouble(), Tolerance); + + [Theory] + [InlineData(0.0)] + [InlineData(123.456)] + [InlineData(-987.654)] + public void ToDouble_Half_ReturnsExpected(Half value) => Assert.Equal((double)value, value.ToDouble(), Tolerance); + + #endregion + + #region Single value conversions (nullable) + + [Fact] + public void ToDouble_NullableByte_Null_ReturnsZero() => Assert.Equal(0.0, ((byte?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableSByte_Null_ReturnsZero() => Assert.Equal(0.0, ((sbyte?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableShort_Null_ReturnsZero() => Assert.Equal(0.0, ((short?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableUShort_Null_ReturnsZero() => Assert.Equal(0.0, ((ushort?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableInt_Null_ReturnsZero() => Assert.Equal(0.0, ((int?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableUInt_Null_ReturnsZero() => Assert.Equal(0.0, ((uint?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableLong_Null_ReturnsZero() => Assert.Equal(0.0, ((long?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableULong_Null_ReturnsZero() => Assert.Equal(0.0, ((ulong?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableNInt_Null_ReturnsZero() => Assert.Equal(0.0, ((nint?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableNUInt_Null_ReturnsZero() => Assert.Equal(0.0, ((nuint?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableFloat_Null_ReturnsZero() => Assert.Equal(0.0, ((float?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableDecimal_Null_ReturnsZero() => Assert.Equal(0.0, ((decimal?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableHalf_Null_ReturnsZero() => Assert.Equal(0.0, ((Half?)null).ToDouble()); + + #endregion + + #region NET7_0_OR_GREATER + +#if NET7_0_OR_GREATER + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(-1)] + [InlineData(long.MaxValue)] + public void ToDouble_Int128_ReturnsExpected(Int128 value) => Assert.Equal((double)value, value.ToDouble(), Tolerance); + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(ulong.MaxValue)] + public void ToDouble_UInt128_ReturnsExpected(UInt128 value) => Assert.Equal((double)value, value.ToDouble(), Tolerance); + + [Fact] + public void ToDouble_NullableInt128_Null_ReturnsZero() => Assert.Equal(0.0, ((Int128?)null).ToDouble()); + + [Fact] + public void ToDouble_NullableUInt128_Null_ReturnsZero() => Assert.Equal(0.0, ((UInt128?)null).ToDouble()); +#endif + + #endregion + + #region IEnumerable -> IEnumerable (non-nullable) + + [Fact] + public void ToDouble_IEnumerableByte_ReturnsCorrect() + { + byte[] source = [1, 2, 3]; + var result = source.ToDouble(); + Assert.Equal(new double[] { 1, 2, 3 }, result); + } + + [Fact] + public void ToDouble_IEnumerableByte_Empty_ReturnsEmpty() + { + var source = Array.Empty(); + var result = source.ToDouble(); + Assert.Empty(result); + } + + [Fact] + public void ToDouble_IEnumerableByte_Null_Throws() => Assert.Null(((IEnumerable)null!).ToDouble()); + + [Fact] + public void ToDouble_IEnumerableInt_ReturnsCorrect() + { + int[] source = [-5, 0, 10]; + var result = source.ToDouble(); + Assert.Equal(new double[] { -5, 0, 10 }, result); + } + + [Fact] + public void ToDouble_IEnumerableInt_Null_Throws() => Assert.Null(((IEnumerable)null!).ToDouble()); + + #endregion + + #region IEnumerable -> IEnumerable + + [Fact] + public void ToDouble_IEnumerableNullableInt_ReturnsCorrect() + { + int?[] source = [1, null, 3]; + var result = source.ToDouble(); + Assert.Equal(3, result.Length); + Assert.Equal(1.0, result.First()); + Assert.Null(result.Skip(1).First()); + Assert.Equal(3.0, result.Last()); + } + + [Fact] + public void ToDouble_IEnumerableNullableInt_Null_Throws() => Assert.Null(((IEnumerable)null!).ToDouble()); + + #endregion + + #region Array and List conversions (non-nullable) + + [Fact] + public void ToDouble_ByteArray_ReturnsDoubleArray() + { + byte[] arr = [10, 20]; + var result = arr.ToDouble(); + Assert.Equal(new double[] { 10, 20 }, result); + } + + [Fact] + public void ToDouble_ByteArray_Null_ReturnsNull() => Assert.Null(((byte[])null!).ToDouble()); + + [Fact] + public void ToDouble_ByteList_ReturnsDoubleList() + { + var list = new List { 10, 20 }; + var result = list.ToDouble(); + Assert.Equal([10, 20], result); + } + + [Fact] + public void ToDouble_ByteList_Null_ReturnsNull() => Assert.Null(((List)null!).ToDouble()); + + [Fact] + public void ToDouble_IntArray_ReturnsDoubleArray() + { + int[] arr = [-5, 0, 7]; + var result = arr.ToDouble(); + Assert.Equal(new double[] { -5, 0, 7 }, result); + } + + [Fact] + public void ToDouble_IntList_ReturnsDoubleList() + { + var list = new List { -5, 0, 7 }; + var result = list.ToDouble(); + Assert.Equal([-5, 0, 7], result); + } + + #endregion + + #region Array and List conversions (nullable) + + [Fact] + public void ToDouble_NullableIntArray_ReturnsNullableDoubleArray() + { + int?[] arr = [1, null, 3]; + var result = arr.ToDouble(); + Assert.Equal(3, result.Length); + Assert.Equal(1.0, result[0]); + Assert.Null(result[1]); + Assert.Equal(3.0, result[2]); + } + + [Fact] + public void ToDouble_NullableIntArray_Null_ReturnsNull() => Assert.Null(((int?[])null!).ToDouble()); + + [Fact] + public void ToDouble_NullableIntList_ReturnsNullableDoubleList() + { + var list = new List { 1, null, 3 }; + var result = list.ToDouble(); + Assert.Equal(3, result.Count); + Assert.Equal(1.0, result[0]); + Assert.Null(result[1]); + Assert.Equal(3.0, result[2]); + } + + [Fact] + public void ToDouble_NullableIntList_Null_ReturnsNull() => Assert.Null(((List)null!).ToDouble()); + + #endregion + + #region IReadOnlyCollection -> Span + + [Fact] + public void ToDouble_IReadOnlyCollectionByte_Span_Works() + { + byte[] source = [1, 2]; + Span dest = new double[source.Length]; + ((IReadOnlyCollection)source).ToDouble(dest); + Assert.Equal(1.0, dest[0]); + Assert.Equal(2.0, dest[1]); + } + + [Fact] + public void ToDouble_IReadOnlyCollectionByte_EmptySpan_Works() + { + byte[] source = []; + Span dest = []; + ((IReadOnlyCollection)source).ToDouble(dest); + } + + [Fact] + public void ToDouble_IReadOnlyCollectionByte_DestinationTooShort_Throws() + { + byte[] source = [1, 2]; + Assert.Throws(() => + { + Span dest = new double[1]; + ((IReadOnlyCollection)source).ToDouble(dest); + }); + } + + [Fact] + public void ToDouble_IReadOnlyCollectionNullableInt_Span_HandlesNulls() + { + int?[] source = [1, null, 3]; + Span dest = new double?[3]; + ((IReadOnlyCollection)source).ToDouble(dest); + Assert.Equal(1.0, dest[0]); + Assert.Null(dest[1]); + Assert.Equal(3.0, dest[2]); + } + + #endregion + + #region Span conversions (ToDoubleCore) - через массивы + + [Fact] + public void IntSpan_ToDouble_ConversionWorks() + { + int[] source = [1, 2, 3]; + var result = source.ToDouble(); + Assert.Equal(new double[] { 1, 2, 3 }, result); + } + + [Fact] + public void FloatSpan_ToDouble_ConversionWorks() + { + float[] source = [1.1f, -2.2f]; + var result = source.ToDouble(); + Assert.Equal(1.1f, result[0], Tolerance); + Assert.Equal(-2.2f, result[1], Tolerance); + } + + [Fact] + public void NullableDecimalSpan_ToDouble_HandlesNulls() + { + decimal?[] source = [1.5m, null, -3.3m]; + var result = source.ToDouble(); + Assert.Equal(3, result.Length); + Assert.Equal(1.5, result[0]!.Value, Tolerance); + Assert.Null(result[1]); + Assert.Equal(-3.3, result[2]!.Value, Tolerance); + } + + #endregion + + #region Edge cases + + [Fact] + public void ToDouble_LongMaxValue_DoesNotOverflow() + { + long max = long.MaxValue; + double result = max.ToDouble(); + Assert.Equal((double)max, result, Tolerance); + } + + [Fact] + public void ToDouble_ULongMaxValue_DoesNotOverflow() + { + ulong max = ulong.MaxValue; + double result = max.ToDouble(); + Assert.Equal((double)max, result, Tolerance); + } + + [Fact] + public void ToDouble_Decimal_HighPrecision_DoesNotCrash() + { + decimal huge = decimal.MaxValue; + var result = huge.ToDouble(); + Assert.False(double.IsInfinity(result)); + } + + #endregion + } +} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Extensions/CastExtensions.cs b/QWERTYkez.Mensura/Extensions/CastExtensions.cs index 01f7fae..106f29c 100644 --- a/QWERTYkez.Mensura/Extensions/CastExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/CastExtensions.cs @@ -5,13 +5,19 @@ namespace QWERTYkez.Mensura.Extensions; internal static partial class CastExtensions { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static double ToDouble(this T unit) where T : struct, IMensuraUnit, IEquatable - => Unsafe.As(ref unit); + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double ToDouble(this T unit) + where T : struct, IMensuraUnit, IEquatable => Unsafe.As(ref unit); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Protected(this T? unit) + where T : struct, IMensuraUnit, IEquatable => unit.GetValueOrDefault().ToDouble(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static T ProtectedU(this T? unit) + where T : struct, IMensuraUnit, IEquatable => unit ?? default; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static T ToUnit(this double val) where T : struct, IMensuraUnit, IEquatable => Unsafe.As(ref val); + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static List WrapAsList(this T[] array) where T : struct, IMensuraUnit, IEquatable diff --git a/QWERTYkez.Mensura/Extensions/CollectionsDivideExtensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsDivideExtensions.cs index e7a7f3f..08374a2 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsDivideExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsDivideExtensions.cs @@ -2,8 +2,8 @@ internal static partial class CollectionsDivideExtensions { - // === DivideCore === SIMD - internal static void DivideCore(this ReadOnlySpan units, double divisor, int len, Span destination) + // === DivCore === SIMD + internal static void DivCore(this ReadOnlySpan units, double divisor, int len, Span destination) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { @@ -40,7 +40,7 @@ internal static partial class CollectionsDivideExtensions Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * invDivisor; } } - internal static void DivideCore(this ReadOnlySpan units, double divisor, int len, Span destination) + internal static void DivCore(this ReadOnlySpan units, double divisor, int len, Span destination) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { @@ -67,10 +67,10 @@ internal static partial class CollectionsDivideExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (u0.Value.ToDouble() * invDivisor).ToUnit() : null; - d1 = u1.HasValue ? (u1.Value.ToDouble() * invDivisor).ToUnit() : null; - d2 = u2.HasValue ? (u2.Value.ToDouble() * invDivisor).ToUnit() : null; - d3 = u3.HasValue ? (u3.Value.ToDouble() * invDivisor).ToUnit() : null; + d0 = (u0.Protected() * invDivisor).ToUnit(); + d1 = (u1.Protected() * invDivisor).ToUnit(); + d2 = (u2.Protected() * invDivisor).ToUnit(); + d3 = (u3.Protected() * invDivisor).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -78,12 +78,11 @@ internal static partial class CollectionsDivideExtensions { T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? (unit.Value.ToDouble() * invDivisor).ToUnit() : null; + dst = (unit.Protected() * invDivisor).ToUnit(); } } //SIMD - internal static void DivideCore(this double dividend, ReadOnlySpan units, int len, Span destination) + internal static void DivCore(this double dividend, ReadOnlySpan units, int len, Span destination) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { @@ -118,7 +117,7 @@ internal static partial class CollectionsDivideExtensions Unsafe.Add(ref dstRef, i) = dividend / Unsafe.Add(ref srcRef, i); } } - internal static void DivideCore(this double dividend, ReadOnlySpan units, int len, Span destination) + internal static void DivCore(this double dividend, ReadOnlySpan units, int len, Span destination) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { @@ -144,10 +143,10 @@ internal static partial class CollectionsDivideExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (dividend / u0.Value.ToDouble()).ToUnit() : null; - d1 = u1.HasValue ? (dividend / u1.Value.ToDouble()).ToUnit() : null; - d2 = u2.HasValue ? (dividend / u2.Value.ToDouble()).ToUnit() : null; - d3 = u3.HasValue ? (dividend / u3.Value.ToDouble()).ToUnit() : null; + d0 = (dividend / u0.Protected()).ToUnit(); + d1 = (dividend / u1.Protected()).ToUnit(); + d2 = (dividend / u2.Protected()).ToUnit(); + d3 = (dividend / u3.Protected()).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -156,7 +155,7 @@ internal static partial class CollectionsDivideExtensions T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - dst = unit.HasValue ? (dividend / unit.Value.ToDouble()).ToUnit() : null; + dst = (dividend / unit.Protected()).ToUnit(); } } @@ -174,7 +173,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new R[len]; - units.DivideCore(divisor, len, result); + units.DivCore(divisor, len, result); return result; } internal static R?[] Div(this T?[] units, double divisor) @@ -186,7 +185,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new R?[len]; - units.DivideCore(divisor, len, result); + units.DivCore(divisor, len, result); return result; } internal static R[] Div(this double dividend, T[] units) @@ -198,7 +197,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new R[len]; - dividend.DivideCore(units, len, result); + dividend.DivCore(units, len, result); return result; } internal static R?[] Div(this double dividend, T?[] units) @@ -210,7 +209,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new R?[len]; - dividend.DivideCore(units, len, result); + dividend.DivCore(units, len, result); return result; } @@ -223,9 +222,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - DivideCore(CollectionsMarshal.AsSpan(units), divisor, count, resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + DivCore(CollectionsMarshal.AsSpan(units), divisor, count, result); + return result.WrapAsList(); } internal static List Div(this List units, double divisor) where T : struct, IMensuraUnit, IEquatable @@ -235,9 +234,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - DivideCore(CollectionsMarshal.AsSpan(units), divisor, count, resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + DivCore(CollectionsMarshal.AsSpan(units), divisor, count, result); + return result.WrapAsList(); } internal static List Div(this double dividend, List units) where T : struct, IMensuraUnit, IEquatable @@ -247,9 +246,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - DivideCore(dividend, CollectionsMarshal.AsSpan(units), count, resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + DivCore(dividend, CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } internal static List Div(this double dividend, List units) where T : struct, IMensuraUnit, IEquatable @@ -259,9 +258,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - DivideCore(dividend, CollectionsMarshal.AsSpan(units), count, resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + DivCore(dividend, CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -275,8 +274,8 @@ internal static partial class CollectionsDivideExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { array.DivideCore(divisor, count, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).DivideCore(divisor, count, destination); return; } + if (units is T[] array) { array.DivCore(divisor, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).DivCore(divisor, count, destination); return; } int i = 0; double invDivisor = 1.0 / divisor; @@ -293,14 +292,13 @@ internal static partial class CollectionsDivideExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.DivideCore(divisor, count, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).DivideCore(divisor, count, destination); return; } + if (units is T?[] array) { array.DivCore(divisor, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).DivCore(divisor, count, destination); return; } int i = 0; double invDivisor = 1.0 / divisor; foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() * invDivisor).ToUnit() : null; + destination[i++] = (item.Protected() * invDivisor).ToUnit(); } internal static void Div(this double dividend, IReadOnlyCollection units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -312,8 +310,8 @@ internal static partial class CollectionsDivideExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { dividend.DivideCore(array, count, destination); return; } - if (units is List list) { dividend.DivideCore(CollectionsMarshal.AsSpan(list), count, destination); return; } + if (units is T[] array) { dividend.DivCore(array, count, destination); return; } + if (units is List list) { dividend.DivCore(CollectionsMarshal.AsSpan(list), count, destination); return; } int i = 0; foreach (var item in units) @@ -329,13 +327,12 @@ internal static partial class CollectionsDivideExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { dividend.DivideCore(array, count, destination); return; } - if (units is List list) { dividend.DivideCore(CollectionsMarshal.AsSpan(list), count, destination); return; } + if (units is T?[] array) { dividend.DivCore(array, count, destination); return; } + if (units is List list) { dividend.DivCore(CollectionsMarshal.AsSpan(list), count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (dividend / item.Value.ToDouble()).ToUnit() : null; + destination[i++] = (dividend / item.Protected()).ToUnit(); } // === IEnumerable + yeild === @@ -353,8 +350,7 @@ internal static partial class CollectionsDivideExtensions { double invDivisor = 1.0 / divisor; foreach (T? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() * invDivisor).ToUnit() : null; + yield return (item.Protected() * invDivisor).ToUnit(); } static IEnumerable DivideIterator(double dividend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable @@ -368,8 +364,7 @@ internal static partial class CollectionsDivideExtensions where R : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (dividend / item.Value.ToDouble()).ToUnit() : null; + yield return (dividend / item.Protected()).ToUnit(); } // === IEnumerable === @@ -383,7 +378,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Div(divisor, arr); + arr.DivCore(divisor, arr.Length, arr); return arr.ReCast(); } return DivideIterator(units, divisor); @@ -398,7 +393,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Div(divisor, arr); + arr.DivCore(divisor, arr.Length, arr); return arr.ReCast(); } return DivideNullableIterator(units, divisor); @@ -413,7 +408,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - dividend.Div(arr, arr); + dividend.DivCore(arr, arr.Length, arr); return arr.ReCast(); } return DivideIterator(dividend, units); @@ -428,7 +423,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - dividend.Div(arr, arr); + dividend.DivCore(arr, arr.Length, arr); return arr.ReCast(); } return DivideNullableIterator(dividend, units); @@ -447,7 +442,7 @@ internal static partial class CollectionsDivideExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.DivideCore(divisor, len, destination); + units.DivCore(divisor, len, destination); } internal static void Div(this ReadOnlySpan units, double divisor, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -457,7 +452,7 @@ internal static partial class CollectionsDivideExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.DivideCore(divisor, len, destination); + units.DivCore(divisor, len, destination); } internal static void Div(this double dividend, ReadOnlySpan units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -467,7 +462,7 @@ internal static partial class CollectionsDivideExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - dividend.DivideCore(units, len, destination); + dividend.DivCore(units, len, destination); } internal static void Div(this double dividend, ReadOnlySpan units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -477,7 +472,7 @@ internal static partial class CollectionsDivideExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - dividend.DivideCore(units, len, destination); + dividend.DivCore(units, len, destination); } // === Array === @@ -489,7 +484,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T[len]; - Div(units, divisor, result); + units.DivCore(divisor, len, result); return result; } internal static T?[] Div(this T?[] units, double divisor) @@ -500,7 +495,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T?[len]; - Div(units, divisor, result); + units.DivCore(divisor, len, result); return result; } internal static T[] Div(this double dividend, T[] units) @@ -511,7 +506,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T[len]; - Div(dividend, units, result); + dividend.DivCore(units, len, result); return result; } internal static T?[] Div(this double dividend, T?[] units) @@ -522,7 +517,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T?[len]; - Div(dividend, units, result); + dividend.DivCore(units, len, result); return result; } @@ -531,12 +526,12 @@ internal static partial class CollectionsDivideExtensions where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new T[len]; - Div(CollectionsMarshal.AsSpan(units), divisor, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + CollectionsMarshal.AsSpan(units).DivCore(divisor, count, result); + return result.WrapAsList(); } internal static List Div(this List units, double divisor) where T : struct, IMensuraUnit, IEquatable @@ -545,9 +540,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Div(CollectionsMarshal.AsSpan(units), divisor, resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + CollectionsMarshal.AsSpan(units).DivCore(divisor, count, result); + return result.WrapAsList(); } internal static List Div(this double dividend, List units) where T : struct, IMensuraUnit, IEquatable @@ -556,9 +551,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T[count]; - Div(dividend, CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + dividend.DivCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } internal static List Div(this double dividend, List units) where T : struct, IMensuraUnit, IEquatable @@ -567,9 +562,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Div(dividend, CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + dividend.DivCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -605,8 +600,7 @@ internal static partial class CollectionsDivideExtensions int i = 0; double invDivisor = 1.0 / divisor; foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() * invDivisor).ToUnit() : null; + destination[i++] = (item.Protected() * invDivisor).ToUnit(); } internal static void Div(this double dividend, IReadOnlyCollection units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -638,8 +632,7 @@ internal static partial class CollectionsDivideExtensions int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (dividend / item.Value.ToDouble()).ToUnit() : null; + destination[i++] = (dividend / item.Protected()).ToUnit(); } // === IEnumerable + yeild === @@ -655,8 +648,7 @@ internal static partial class CollectionsDivideExtensions { double invDivisor = 1.0 / divisor; foreach (T? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() * invDivisor).ToUnit() : null; + yield return (item.Protected() * invDivisor).ToUnit(); } static IEnumerable DivideIterator(double dividend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable @@ -668,8 +660,7 @@ internal static partial class CollectionsDivideExtensions where T : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (dividend / item.Value.ToDouble()).ToUnit() : null; + yield return (dividend / item.Protected()).ToUnit(); } // === IEnumerable === @@ -682,7 +673,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Div(divisor, arr); + arr.DivCore(divisor, arr.Length, arr); return arr; } return DivideIterator(units, divisor); @@ -696,7 +687,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Div(divisor, arr); + arr.DivCore(divisor, arr.Length, arr); return arr; } return DivideNullableIterator(units, divisor); @@ -710,7 +701,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - dividend.Div(arr, arr); + dividend.DivCore(arr, arr.Length, arr); return arr; } return DivideIterator(dividend, units); @@ -724,7 +715,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - dividend.Div(arr, arr); + dividend.DivCore(arr, arr.Length, arr); return arr; } return DivideNullableIterator(dividend, units); @@ -738,7 +729,7 @@ internal static partial class CollectionsDivideExtensions - // === DivideCore === SIMD + // === DivCore === SIMD internal static void DivCore(this ReadOnlySpan dividends, double unit, int len, Span destination) where R : struct, IMensuraUnit, IEquatable { @@ -800,10 +791,10 @@ internal static partial class CollectionsDivideExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (u0.Value * invDivisor).ToUnit() : null; - d1 = u1.HasValue ? (u1.Value * invDivisor).ToUnit() : null; - d2 = u2.HasValue ? (u2.Value * invDivisor).ToUnit() : null; - d3 = u3.HasValue ? (u3.Value * invDivisor).ToUnit() : null; + d0 = ((u0 ?? 0d) * invDivisor).ToUnit(); + d1 = ((u1 ?? 0d) * invDivisor).ToUnit(); + d2 = ((u2 ?? 0d) * invDivisor).ToUnit(); + d3 = ((u3 ?? 0d) * invDivisor).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -811,8 +802,7 @@ internal static partial class CollectionsDivideExtensions { var div = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = div.HasValue ? (div.Value * invDivisor).ToUnit() : null; + dst = ((div ?? 0d) * invDivisor).ToUnit(); } } //SIMD @@ -874,10 +864,10 @@ internal static partial class CollectionsDivideExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (unit / u0.Value).ToUnit() : null; - d1 = u1.HasValue ? (unit / u1.Value).ToUnit() : null; - d2 = u2.HasValue ? (unit / u2.Value).ToUnit() : null; - d3 = u3.HasValue ? (unit / u3.Value).ToUnit() : null; + d0 = (unit / (u0 ?? 0d)).ToUnit(); + d1 = (unit / (u1 ?? 0d)).ToUnit(); + d2 = (unit / (u2 ?? 0d)).ToUnit(); + d3 = (unit / (u3 ?? 0d)).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -886,12 +876,12 @@ internal static partial class CollectionsDivideExtensions var div = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - dst = div.HasValue ? (unit / div.Value).ToUnit() : null; + dst = (unit / (div ?? 0d)).ToUnit(); } } - // === DivideCore === SIMD + // === DivCore === SIMD internal static void DivCore(this ReadOnlySpan dividends, double unit, int len, Span dstDouble) { // Вместо деления в цикле, умножаем на обратное число (invDivisor) @@ -949,10 +939,10 @@ internal static partial class CollectionsDivideExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? u0.Value * invDivisor : null; - d1 = u1.HasValue ? u1.Value * invDivisor : null; - d2 = u2.HasValue ? u2.Value * invDivisor : null; - d3 = u3.HasValue ? u3.Value * invDivisor : null; + d0 = (u0 ?? 0d) * invDivisor; + d1 = (u1 ?? 0d) * invDivisor; + d2 = (u2 ?? 0d) * invDivisor; + d3 = (u3 ?? 0d) * invDivisor; } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -960,8 +950,7 @@ internal static partial class CollectionsDivideExtensions { double? div = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = div.HasValue ? div.Value * invDivisor : null; + dst = (div ?? 0d) * invDivisor; } } //SIMD @@ -1019,10 +1008,10 @@ internal static partial class CollectionsDivideExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? dUnit / u0.Value : null; - d1 = u1.HasValue ? dUnit / u1.Value : null; - d2 = u2.HasValue ? dUnit / u2.Value : null; - d3 = u3.HasValue ? dUnit / u3.Value : null; + d0 = dUnit / (u0 ?? 0d); + d1 = dUnit / (u1 ?? 0d); + d2 = dUnit / (u2 ?? 0d); + d3 = dUnit / (u3 ?? 0d); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -1030,8 +1019,7 @@ internal static partial class CollectionsDivideExtensions { double? div = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = div.HasValue ? dUnit / div.Value : null; + dst = dUnit / (div ?? 0d); } } @@ -1090,7 +1078,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T[len]; - Div(units, divisor, result); + units.DivCore(divisor.ToDouble(), len, result); return result; } internal static T?[] Div(this double?[] units, T divisor) @@ -1101,7 +1089,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T?[len]; - Div(units, divisor, result); + units.DivCore(divisor.ToDouble(), len, result); return result; } internal static T[] Div(this T dividend, double[] units) @@ -1112,7 +1100,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T[len]; - Div(dividend, units, result); + dividend.ToDouble().DivCore(units, len, result); return result; } internal static T?[] Div(this T dividend, double?[] units) @@ -1123,7 +1111,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T?[len]; - Div(dividend, units, result); + dividend.ToDouble().DivCore(units, len, result); return result; } @@ -1132,12 +1120,12 @@ internal static partial class CollectionsDivideExtensions where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new T[len]; - Div(CollectionsMarshal.AsSpan(units), divisor, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + CollectionsMarshal.AsSpan(units).DivCore(divisor.ToDouble(), count, result); + return result.WrapAsList(); } internal static List Div(this List units, T divisor) where T : struct, IMensuraUnit, IEquatable @@ -1146,9 +1134,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Div(CollectionsMarshal.AsSpan(units), divisor, resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + CollectionsMarshal.AsSpan(units).DivCore(divisor.ToDouble(), count, result); + return result.WrapAsList(); } internal static List Div(this T dividend, List units) where T : struct, IMensuraUnit, IEquatable @@ -1157,9 +1145,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T[count]; - Div(dividend, CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + dividend.ToDouble().DivCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } internal static List Div(this T dividend, List units) where T : struct, IMensuraUnit, IEquatable @@ -1168,9 +1156,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Div(dividend, CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + dividend.ToDouble().DivCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -1206,8 +1194,7 @@ internal static partial class CollectionsDivideExtensions int i = 0; double invDivisor = 1.0 / divisor.ToDouble(); foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value * invDivisor).ToUnit() : null; + destination[i++] = ((item ?? 0d) * invDivisor).ToUnit(); } internal static void Div(this T dividend, IReadOnlyCollection units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -1238,9 +1225,9 @@ internal static partial class CollectionsDivideExtensions if (units is List list) { dividend.Div(CollectionsMarshal.AsSpan(list), destination); return; } int i = 0; + var divD = dividend.ToDouble(); foreach (var item in units) - destination[i++] = item.HasValue - ? (dividend.ToDouble() / item.Value).ToUnit() : null; + destination[i++] = (divD / (item ?? 0d)).ToUnit(); } // === IEnumerable + yeild === @@ -1256,8 +1243,7 @@ internal static partial class CollectionsDivideExtensions { double invDivisor = 1.0 / divisor; foreach (var item in units) - yield return item.HasValue - ? (item.Value * invDivisor).ToUnit() : null; + yield return ((item ?? 0d) * invDivisor).ToUnit(); } static IEnumerable DivideIterator(double dividend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable @@ -1269,8 +1255,7 @@ internal static partial class CollectionsDivideExtensions where T : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? (dividend / item.Value).ToUnit() : null; + yield return (dividend / (item ?? 0d)).ToUnit(); } // === IEnumerable === @@ -1339,8 +1324,8 @@ internal static partial class CollectionsDivideExtensions - // === DivideCore === SIMD - internal static void DivideCore(this ReadOnlySpan units, double divisor, int len, Span dstDouble) + // === DivCore === SIMD + internal static void DivCore(this ReadOnlySpan units, double divisor, int len, Span dstDouble) where T : struct, IMensuraUnit, IEquatable { ReadOnlySpan srcDouble = MemoryMarshal.Cast(units); @@ -1375,7 +1360,7 @@ internal static partial class CollectionsDivideExtensions Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * invDivisor; } } - internal static void DivideCore(this ReadOnlySpan units, double divisor, int len, Span destination) + internal static void DivCore(this ReadOnlySpan units, double divisor, int len, Span destination) where T : struct, IMensuraUnit, IEquatable { // Получаем прямые неуправляемые ref-ссылки на начало буферов за 0 тактов @@ -1401,10 +1386,10 @@ internal static partial class CollectionsDivideExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? u0.Value.ToDouble() * invDivisor : null; - d1 = u1.HasValue ? u1.Value.ToDouble() * invDivisor : null; - d2 = u2.HasValue ? u2.Value.ToDouble() * invDivisor : null; - d3 = u3.HasValue ? u3.Value.ToDouble() * invDivisor : null; + d0 = u0.Protected() * invDivisor; + d1 = u1.Protected() * invDivisor; + d2 = u2.Protected() * invDivisor; + d3 = u3.Protected() * invDivisor; } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -1413,11 +1398,11 @@ internal static partial class CollectionsDivideExtensions T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - dst = unit.HasValue ? unit.Value.ToDouble() * invDivisor : null; + dst = unit.Protected() * invDivisor; } } //SIMD - internal static void DivideCore(this double dividend, ReadOnlySpan units, int len, Span dstDouble) + internal static void DivCore(this double dividend, ReadOnlySpan units, int len, Span dstDouble) where T : struct, IMensuraUnit, IEquatable { ReadOnlySpan srcDouble = MemoryMarshal.Cast(units); @@ -1450,7 +1435,7 @@ internal static partial class CollectionsDivideExtensions Unsafe.Add(ref dstRef, i) = dividend / Unsafe.Add(ref srcRef, i); } } - internal static void DivideCore(this double dividend, ReadOnlySpan units, int len, Span destination) + internal static void DivCore(this double dividend, ReadOnlySpan units, int len, Span destination) where T : struct, IMensuraUnit, IEquatable { // Получаем прямые неуправляемые ref-ссылки на начало буферов за 0 тактов @@ -1475,10 +1460,10 @@ internal static partial class CollectionsDivideExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? dividend / u0.Value.ToDouble() : null; - d1 = u1.HasValue ? dividend / u1.Value.ToDouble() : null; - d2 = u2.HasValue ? dividend / u2.Value.ToDouble() : null; - d3 = u3.HasValue ? dividend / u3.Value.ToDouble() : null; + d0 = dividend / u0.Protected(); + d1 = dividend / u1.Protected(); + d2 = dividend / u2.Protected(); + d3 = dividend / u3.Protected(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -1487,7 +1472,7 @@ internal static partial class CollectionsDivideExtensions T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - dst = unit.HasValue ? dividend / unit.Value.ToDouble() : null; + dst = dividend / unit.Protected(); } } @@ -1504,7 +1489,7 @@ internal static partial class CollectionsDivideExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.DivideCore(divisor.ToDouble(), len, destination); + units.DivCore(divisor.ToDouble(), len, destination); } internal static void Div(this ReadOnlySpan units, T divisor, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -1514,7 +1499,7 @@ internal static partial class CollectionsDivideExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.DivideCore(divisor.ToDouble(), len, destination); + units.DivCore(divisor.ToDouble(), len, destination); } internal static void Div(this T dividend, ReadOnlySpan units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -1524,7 +1509,7 @@ internal static partial class CollectionsDivideExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - dividend.ToDouble().DivideCore(units, len, destination); + dividend.ToDouble().DivCore(units, len, destination); } internal static void Div(this T dividend, ReadOnlySpan units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -1534,7 +1519,7 @@ internal static partial class CollectionsDivideExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - dividend.ToDouble().DivideCore(units, len, destination); + dividend.ToDouble().DivCore(units, len, destination); } // === Array === @@ -1546,7 +1531,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T[len]; - units.DivideCore(divisor.ToDouble(), len, result); + units.DivCore(divisor.ToDouble(), len, result); return result.ReCast(); } internal static double?[] Div(this T?[] units, T divisor) @@ -1557,7 +1542,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T?[len]; - units.DivideCore(divisor.ToDouble(), len, result); + units.DivCore(divisor.ToDouble(), len, result); return result.ReCast(); } internal static double[] Div(this T dividend, T[] units) @@ -1568,7 +1553,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T[len]; - dividend.ToDouble().DivideCore(units, len, result); + dividend.ToDouble().DivCore(units, len, result); return result.ReCast(); } internal static double?[] Div(this T dividend, T?[] units) @@ -1579,7 +1564,7 @@ internal static partial class CollectionsDivideExtensions if (len == 0) return []; var result = new T?[len]; - dividend.ToDouble().DivideCore(units, len, result); + dividend.ToDouble().DivCore(units, len, result); return result.ReCast(); } @@ -1591,9 +1576,9 @@ internal static partial class CollectionsDivideExtensions int len = units.Count; if (len == 0) return []; - var resultArray = new double[len]; - CollectionsMarshal.AsSpan(units).DivideCore(divisor.ToDouble(), len, resultArray); - return resultArray.WrapAsList(); + var result = new double[len]; + CollectionsMarshal.AsSpan(units).DivCore(divisor.ToDouble(), len, result); + return result.WrapAsList(); } internal static List Div(this List units, T divisor) where T : struct, IMensuraUnit, IEquatable @@ -1602,9 +1587,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new double?[count]; - CollectionsMarshal.AsSpan(units).DivideCore(divisor.ToDouble(), count, resultArray); - return resultArray.WrapAsList(); + var result = new double?[count]; + CollectionsMarshal.AsSpan(units).DivCore(divisor.ToDouble(), count, result); + return result.WrapAsList(); } internal static List Div(this T dividend, List units) where T : struct, IMensuraUnit, IEquatable @@ -1613,9 +1598,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T[count]; - dividend.ToDouble().DivideCore(CollectionsMarshal.AsSpan(units), count, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + dividend.ToDouble().DivCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } internal static List Div(this T dividend, List units) where T : struct, IMensuraUnit, IEquatable @@ -1624,9 +1609,9 @@ internal static partial class CollectionsDivideExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - dividend.ToDouble().DivideCore(CollectionsMarshal.AsSpan(units), count, resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + dividend.ToDouble().DivCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -1662,7 +1647,7 @@ internal static partial class CollectionsDivideExtensions int i = 0; double invDivisor = 1.0 / divisor.ToDouble(); foreach (var item in units) - destination[i++] = item.HasValue ? item.Value.ToDouble() * invDivisor : null; + destination[i++] = item.Protected() * invDivisor; } internal static void Div(this T dividend, IReadOnlyCollection units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -1696,7 +1681,7 @@ internal static partial class CollectionsDivideExtensions int i = 0; var div = dividend.ToDouble(); foreach (var item in units) - destination[i++] = item.HasValue ? div / item.Value.ToDouble() : null; + destination[i++] = div / item.Protected(); } // === IEnumerable + yeild === @@ -1712,7 +1697,7 @@ internal static partial class CollectionsDivideExtensions { double invDivisor = 1.0 / divisor.ToDouble(); foreach (var item in units) - yield return item.HasValue ? item.Value.ToDouble() * invDivisor : null; + yield return item.Protected() * invDivisor; } static IEnumerable DivideIterator(T dividend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable @@ -1726,7 +1711,7 @@ internal static partial class CollectionsDivideExtensions { var div = dividend.ToDouble(); foreach (var item in units) - yield return item.HasValue ? div / item.Value.ToDouble() : null; + yield return div / item.Protected(); } // === IEnumerable === @@ -1739,7 +1724,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.DivideCore(divisor.ToDouble(), arr.Length, arr); + arr.DivCore(divisor.ToDouble(), arr.Length, arr); return arr.ReCast(); } return DivideIterator(units, divisor); @@ -1753,7 +1738,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.DivideCore(divisor.ToDouble(), arr.Length, arr); + arr.DivCore(divisor.ToDouble(), arr.Length, arr); return arr.ReCast(); } return DivideNullableIterator(units, divisor); @@ -1767,7 +1752,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - dividend.ToDouble().DivideCore(arr, arr.Length, arr); + dividend.ToDouble().DivCore(arr, arr.Length, arr); return arr.ReCast(); } return DivideIterator(dividend, units); @@ -1781,7 +1766,7 @@ internal static partial class CollectionsDivideExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - dividend.ToDouble().DivideCore(arr, arr.Length, arr); + dividend.ToDouble().DivCore(arr, arr.Length, arr); return arr.ReCast(); } return DivideNullableIterator(dividend, units); diff --git a/QWERTYkez.Mensura/Extensions/CollectionsMinusExtensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsMinusExtensions.cs index f5e1e1b..bafd9ef 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsMinusExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsMinusExtensions.cs @@ -62,10 +62,10 @@ internal static partial class CollectionsMinusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (u0.Value.ToDouble() - subtrahend).ToUnit() : null; - d1 = u1.HasValue ? (u1.Value.ToDouble() - subtrahend).ToUnit() : null; - d2 = u2.HasValue ? (u2.Value.ToDouble() - subtrahend).ToUnit() : null; - d3 = u3.HasValue ? (u3.Value.ToDouble() - subtrahend).ToUnit() : null; + d0 = (u0.Protected() - subtrahend).ToUnit(); + d1 = (u1.Protected() - subtrahend).ToUnit(); + d2 = (u2.Protected() - subtrahend).ToUnit(); + d3 = (u3.Protected() - subtrahend).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -73,8 +73,7 @@ internal static partial class CollectionsMinusExtensions { T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? (unit.Value.ToDouble() - subtrahend).ToUnit() : null; + dst = (unit.Protected() - subtrahend).ToUnit(); } } //SIMD @@ -139,10 +138,10 @@ internal static partial class CollectionsMinusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (minuend - u0.Value.ToDouble()).ToUnit() : null; - d1 = u1.HasValue ? (minuend - u1.Value.ToDouble()).ToUnit() : null; - d2 = u2.HasValue ? (minuend - u2.Value.ToDouble()).ToUnit() : null; - d3 = u3.HasValue ? (minuend - u3.Value.ToDouble()).ToUnit() : null; + d0 = (minuend - u0.Protected()).ToUnit(); + d1 = (minuend - u1.Protected()).ToUnit(); + d2 = (minuend - u2.Protected()).ToUnit(); + d3 = (minuend - u3.Protected()).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -150,8 +149,7 @@ internal static partial class CollectionsMinusExtensions { T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? (minuend - unit.Value.ToDouble()).ToUnit() : null; + dst = (minuend - unit.Protected()).ToUnit(); } } @@ -218,9 +216,9 @@ internal static partial class CollectionsMinusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - MinusCore(CollectionsMarshal.AsSpan(units), subtrahend, count, resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + MinusCore(CollectionsMarshal.AsSpan(units), subtrahend, count, result); + return result.WrapAsList(); } internal static List Minus(this List units, double subtrahend) where T : struct, IMensuraUnit, IEquatable @@ -230,9 +228,9 @@ internal static partial class CollectionsMinusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - MinusCore(CollectionsMarshal.AsSpan(units), subtrahend, count, resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + MinusCore(CollectionsMarshal.AsSpan(units), subtrahend, count, result); + return result.WrapAsList(); } internal static List Minus(this double minuend, List units) where T : struct, IMensuraUnit, IEquatable @@ -242,9 +240,9 @@ internal static partial class CollectionsMinusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - MinusCore(minuend, CollectionsMarshal.AsSpan(units), count, resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + MinusCore(minuend, CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } internal static List Minus(this double minuend, List units) where T : struct, IMensuraUnit, IEquatable @@ -254,9 +252,9 @@ internal static partial class CollectionsMinusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - MinusCore(minuend, CollectionsMarshal.AsSpan(units), count, resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + MinusCore(minuend, CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -292,8 +290,7 @@ internal static partial class CollectionsMinusExtensions int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() - subtrahend).ToUnit() : null; + destination[i++] = (item.Protected() - subtrahend).ToUnit(); } internal static void Minus(this double minuend, IReadOnlyCollection units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -327,8 +324,7 @@ internal static partial class CollectionsMinusExtensions int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (minuend - item.Value.ToDouble()).ToUnit() : null; + destination[i++] = (minuend - item.Protected()).ToUnit(); } // === IEnumerable + yeild === @@ -344,8 +340,7 @@ internal static partial class CollectionsMinusExtensions where R : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() - subtrahend).ToUnit() : null; + yield return (item.Protected() - subtrahend).ToUnit(); } static IEnumerable MinusIterator(double minuend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable @@ -359,8 +354,7 @@ internal static partial class CollectionsMinusExtensions where R : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (minuend - item.Value.ToDouble()).ToUnit() : null; + yield return (minuend - item.Protected()).ToUnit(); } // === IEnumerable === @@ -374,7 +368,7 @@ internal static partial class CollectionsMinusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Minus(subtrahend, arr); + arr.MinusCore(subtrahend, arr.Length, arr); return arr.ReCast(); } return MinusIterator(units, subtrahend); @@ -389,7 +383,7 @@ internal static partial class CollectionsMinusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Minus(subtrahend, arr); + arr.MinusCore(subtrahend, arr.Length, arr); return arr.ReCast(); } return MinusNullableIterator(units, subtrahend); @@ -404,7 +398,7 @@ internal static partial class CollectionsMinusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - minuend.Minus(arr, arr); + minuend.MinusCore(arr, arr.Length, arr); return arr.ReCast(); } return MinusIterator(minuend, units); @@ -419,7 +413,7 @@ internal static partial class CollectionsMinusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - minuend.Minus(arr, arr); + minuend.MinusCore(arr, arr.Length, arr); return arr.ReCast(); } return MinusNullableIterator(minuend, units); @@ -481,7 +475,7 @@ internal static partial class CollectionsMinusExtensions if (len == 0) return []; var result = new T[len]; - Minus(units, subtrahend, result); + units.MinusCore(subtrahend, len, result); return result; } internal static T?[] Minus(this T?[] units, double subtrahend) @@ -492,7 +486,7 @@ internal static partial class CollectionsMinusExtensions if (len == 0) return []; var result = new T?[len]; - Minus(units, subtrahend, result); + units.MinusCore(subtrahend, len, result); return result; } internal static T[] Minus(this double minuend, T[] units) @@ -503,7 +497,7 @@ internal static partial class CollectionsMinusExtensions if (len == 0) return []; var result = new T[len]; - Minus(minuend, units, result); + minuend.MinusCore(units, len, result); return result; } internal static T?[] Minus(this double minuend, T?[] units) @@ -514,7 +508,7 @@ internal static partial class CollectionsMinusExtensions if (len == 0) return []; var result = new T?[len]; - Minus(minuend, units, result); + minuend.MinusCore(units, len, result); return result; } @@ -523,12 +517,12 @@ internal static partial class CollectionsMinusExtensions where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new T[len]; - Minus(CollectionsMarshal.AsSpan(units), subtrahend, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + CollectionsMarshal.AsSpan(units).MinusCore(subtrahend, count, result); + return result.WrapAsList(); } internal static List Minus(this List units, double subtrahend) where T : struct, IMensuraUnit, IEquatable @@ -537,9 +531,9 @@ internal static partial class CollectionsMinusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Minus(CollectionsMarshal.AsSpan(units), subtrahend, resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + CollectionsMarshal.AsSpan(units).MinusCore(subtrahend, count, result); + return result.WrapAsList(); } internal static List Minus(this double minuend, List units) where T : struct, IMensuraUnit, IEquatable @@ -548,9 +542,9 @@ internal static partial class CollectionsMinusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T[count]; - Minus(minuend, CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + minuend.MinusCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } internal static List Minus(this double minuend, List units) where T : struct, IMensuraUnit, IEquatable @@ -559,9 +553,9 @@ internal static partial class CollectionsMinusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Minus(minuend, CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + minuend.MinusCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -574,8 +568,8 @@ internal static partial class CollectionsMinusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { array.Minus(subtrahend, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Minus(subtrahend, destination); return; } + if (units is T[] array) { array.MinusCore(subtrahend, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).MinusCore(subtrahend, count, destination); return; } int i = 0; foreach (var item in units) @@ -590,13 +584,12 @@ internal static partial class CollectionsMinusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.Minus(subtrahend, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Minus(subtrahend, destination); return; } + if (units is T?[] array) { array.MinusCore(subtrahend, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).MinusCore(subtrahend, count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() - subtrahend).ToUnit() : null; + destination[i++] = (item.Protected() - subtrahend).ToUnit(); } internal static void Minus(this double minuend, IReadOnlyCollection units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -607,8 +600,8 @@ internal static partial class CollectionsMinusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { minuend.Minus(array, destination); return; } - if (units is List list) { minuend.Minus(CollectionsMarshal.AsSpan(list), destination); return; } + if (units is T[] array) { minuend.MinusCore(array, count, destination); return; } + if (units is List list) { minuend.MinusCore(CollectionsMarshal.AsSpan(list), count, destination); return; } int i = 0; foreach (var item in units) @@ -623,13 +616,12 @@ internal static partial class CollectionsMinusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { minuend.Minus(array, destination); return; } - if (units is List list) { minuend.Minus(CollectionsMarshal.AsSpan(list), destination); return; } + if (units is T?[] array) { minuend.MinusCore(array, count, destination); return; } + if (units is List list) { minuend.MinusCore(CollectionsMarshal.AsSpan(list), count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (minuend - item.Value.ToDouble()).ToUnit() : null; + destination[i++] = (minuend - item.Protected()).ToUnit(); } // === IEnumerable + yeild === @@ -643,8 +635,7 @@ internal static partial class CollectionsMinusExtensions where T : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() - subtrahend).ToUnit() : null; + yield return (item.Protected() - subtrahend).ToUnit(); } static IEnumerable MinusIterator(double minuend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable @@ -656,8 +647,7 @@ internal static partial class CollectionsMinusExtensions where T : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (minuend - item.Value.ToDouble()).ToUnit() : null; + yield return (minuend - item.Protected()).ToUnit(); } // === IEnumerable === @@ -670,7 +660,7 @@ internal static partial class CollectionsMinusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Minus(subtrahend, arr); + arr.MinusCore(subtrahend, arr.Length, arr); return arr; } return MinusIterator(units, subtrahend); @@ -684,7 +674,7 @@ internal static partial class CollectionsMinusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Minus(subtrahend, arr); + arr.MinusCore(subtrahend, arr.Length, arr); return arr; } return MinusNullableIterator(units, subtrahend); @@ -698,7 +688,7 @@ internal static partial class CollectionsMinusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - minuend.Minus(arr, arr); + minuend.MinusCore(arr, arr.Length, arr); return arr; } return MinusIterator(minuend, units); @@ -712,7 +702,7 @@ internal static partial class CollectionsMinusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - minuend.Minus(arr, arr); + minuend.MinusCore(arr, arr.Length, arr); return arr; } return MinusNullableIterator(minuend, units); @@ -783,10 +773,10 @@ internal static partial class CollectionsMinusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (u0.Value - subtrahend).ToUnit() : null; - d1 = u1.HasValue ? (u1.Value - subtrahend).ToUnit() : null; - d2 = u2.HasValue ? (u2.Value - subtrahend).ToUnit() : null; - d3 = u3.HasValue ? (u3.Value - subtrahend).ToUnit() : null; + d0 = ((u0 ?? 0d) - subtrahend).ToUnit(); + d1 = ((u1 ?? 0d) - subtrahend).ToUnit(); + d2 = ((u2 ?? 0d) - subtrahend).ToUnit(); + d3 = ((u3 ?? 0d) - subtrahend).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -794,8 +784,7 @@ internal static partial class CollectionsMinusExtensions { var unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? (unit.Value - subtrahend).ToUnit() : null; + dst = ((unit ?? 0d) - subtrahend).ToUnit(); } } //SIMD @@ -857,10 +846,10 @@ internal static partial class CollectionsMinusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (minuend - u0.Value).ToUnit() : null; - d1 = u1.HasValue ? (minuend - u1.Value).ToUnit() : null; - d2 = u2.HasValue ? (minuend - u2.Value).ToUnit() : null; - d3 = u3.HasValue ? (minuend - u3.Value).ToUnit() : null; + d0 = (minuend - (u0 ?? 0d)).ToUnit(); + d1 = (minuend - (u1 ?? 0d)).ToUnit(); + d2 = (minuend - (u2 ?? 0d)).ToUnit(); + d3 = (minuend - (u3 ?? 0d)).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -868,13 +857,12 @@ internal static partial class CollectionsMinusExtensions { var unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? (minuend - unit.Value).ToUnit() : null; + dst = (minuend - (unit ?? 0d)).ToUnit(); } } - // === DivideCore === SIMD + // === DivCore === SIMD internal static void MinusCore(this ReadOnlySpan srcDouble, double subtrahend, int len, Span dstDouble) { var vectorizedSubtrahend = new Vector(subtrahend); @@ -927,10 +915,10 @@ internal static partial class CollectionsMinusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? u0.Value - subtrahend : null; - d1 = u1.HasValue ? u1.Value - subtrahend : null; - d2 = u2.HasValue ? u2.Value - subtrahend : null; - d3 = u3.HasValue ? u3.Value - subtrahend : null; + d0 = (u0 ?? 0d) - subtrahend; + d1 = (u1 ?? 0d) - subtrahend; + d2 = (u2 ?? 0d) - subtrahend; + d3 = (u3 ?? 0d) - subtrahend; } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -938,8 +926,7 @@ internal static partial class CollectionsMinusExtensions { var unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? unit.Value - subtrahend : null; + dst = (unit ?? 0d) - subtrahend; } } //SIMD @@ -997,10 +984,10 @@ internal static partial class CollectionsMinusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? minuend - u0.Value : null; - d1 = u1.HasValue ? minuend - u1.Value : null; - d2 = u2.HasValue ? minuend - u2.Value : null; - d3 = u3.HasValue ? minuend - u3.Value : null; + d0 = minuend - u0 ?? 0d; + d1 = minuend - u1 ?? 0d; + d2 = minuend - u2 ?? 0d; + d3 = minuend - u3 ?? 0d; } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -1008,8 +995,7 @@ internal static partial class CollectionsMinusExtensions { var unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? minuend - unit.Value : null; + dst = minuend - unit ?? 0d; } } @@ -1018,7 +1004,7 @@ internal static partial class CollectionsMinusExtensions // === ReadOnlySpan - internal static void Minus(this ReadOnlySpan units, T divisor, Span destination) + internal static void Minus(this ReadOnlySpan units, T subtrahend, Span destination) where T : struct, IMensuraUnit, IEquatable { if (units.IsEmpty) return; @@ -1026,9 +1012,9 @@ internal static partial class CollectionsMinusExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.MinusCore(divisor.ToDouble(), len, destination); + units.MinusCore(subtrahend.ToDouble(), len, destination); } - internal static void Minus(this ReadOnlySpan units, T divisor, Span destination) + internal static void Minus(this ReadOnlySpan units, T subtrahend, Span destination) where T : struct, IMensuraUnit, IEquatable { if (units.IsEmpty) return; @@ -1036,9 +1022,9 @@ internal static partial class CollectionsMinusExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.MinusCore(divisor.ToDouble(), len, destination); + units.MinusCore(subtrahend.ToDouble(), len, destination); } - internal static void Minus(this T dividend, ReadOnlySpan units, Span destination) + internal static void Minus(this T minuend, ReadOnlySpan units, Span destination) where T : struct, IMensuraUnit, IEquatable { if (units.IsEmpty) return; @@ -1046,9 +1032,9 @@ internal static partial class CollectionsMinusExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - dividend.ToDouble().MinusCore(units, len, destination); + minuend.ToDouble().MinusCore(units, len, destination); } - internal static void Minus(this T dividend, ReadOnlySpan units, Span destination) + internal static void Minus(this T minuend, ReadOnlySpan units, Span destination) where T : struct, IMensuraUnit, IEquatable { if (units.IsEmpty) return; @@ -1056,11 +1042,11 @@ internal static partial class CollectionsMinusExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - dividend.ToDouble().MinusCore(units, len, destination); + minuend.ToDouble().MinusCore(units, len, destination); } // === Array === - internal static T[] Minus(this double[] units, T divisor) + internal static T[] Minus(this double[] units, T subtrahend) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; @@ -1068,10 +1054,10 @@ internal static partial class CollectionsMinusExtensions if (len == 0) return []; var result = new T[len]; - Minus(units, divisor, result); + units.MinusCore(subtrahend.ToDouble(), len, result); return result; } - internal static T?[] Minus(this double?[] units, T divisor) + internal static T?[] Minus(this double?[] units, T subtrahend) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; @@ -1079,10 +1065,10 @@ internal static partial class CollectionsMinusExtensions if (len == 0) return []; var result = new T?[len]; - Minus(units, divisor, result); + units.MinusCore(subtrahend.ToDouble(), len, result); return result; } - internal static T[] Minus(this T dividend, double[] units) + internal static T[] Minus(this T minuend, double[] units) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; @@ -1090,10 +1076,10 @@ internal static partial class CollectionsMinusExtensions if (len == 0) return []; var result = new T[len]; - Minus(dividend, units, result); + minuend.ToDouble().MinusCore(units, len, result); return result; } - internal static T?[] Minus(this T dividend, double?[] units) + internal static T?[] Minus(this T minuend, double?[] units) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; @@ -1101,58 +1087,58 @@ internal static partial class CollectionsMinusExtensions if (len == 0) return []; var result = new T?[len]; - Minus(dividend, units, result); + minuend.ToDouble().MinusCore(units, len, result); return result; } // === List === - internal static List Minus(this List units, T divisor) - where T : struct, IMensuraUnit, IEquatable - { - if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; - - var resultArray = new T[len]; - Minus(CollectionsMarshal.AsSpan(units), divisor, resultArray); - return resultArray.WrapAsList(); - } - internal static List Minus(this List units, T divisor) + internal static List Minus(this List units, T subtrahend) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Minus(CollectionsMarshal.AsSpan(units), divisor, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + CollectionsMarshal.AsSpan(units).MinusCore(subtrahend.ToDouble(), count, result); + return result.WrapAsList(); } - internal static List Minus(this T dividend, List units) + internal static List Minus(this List units, T subtrahend) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; int count = units.Count; if (count == 0) return []; - var resultArray = new T[count]; - Minus(dividend, CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + CollectionsMarshal.AsSpan(units).MinusCore(subtrahend.ToDouble(), count, result); + return result.WrapAsList(); } - internal static List Minus(this T dividend, List units) + internal static List Minus(this T minuend, List units) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Minus(dividend, CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + minuend.ToDouble().MinusCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); + } + internal static List Minus(this T minuend, List units) + where T : struct, IMensuraUnit, IEquatable + { + if (units is null) return null!; + int count = units.Count; + if (count == 0) return []; + + var result = new T?[count]; + minuend.ToDouble().MinusCore(CollectionsMarshal.AsSpan(units), count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === - internal static void Minus(this IReadOnlyCollection units, T divisor, Span destination) + internal static void Minus(this IReadOnlyCollection units, T subtrahend, Span destination) where T : struct, IMensuraUnit, IEquatable { if (units is null) return; @@ -1161,15 +1147,15 @@ internal static partial class CollectionsMinusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is double[] array) { array.Minus(divisor, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Minus(divisor, destination); return; } + if (units is double[] array) { array.MinusCore(subtrahend.ToDouble(), count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).MinusCore(subtrahend.ToDouble(), count, destination); return; } int i = 0; - double invMinusisor = 1.0 / divisor.ToDouble(); + double invMinusisor = 1.0 / subtrahend.ToDouble(); foreach (var item in units) destination[i++] = (item * invMinusisor).ToUnit(); } - internal static void Minus(this IReadOnlyCollection units, T divisor, Span destination) + internal static void Minus(this IReadOnlyCollection units, T subtrahend, Span destination) where T : struct, IMensuraUnit, IEquatable { if (units is null) return; @@ -1178,16 +1164,15 @@ internal static partial class CollectionsMinusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is double?[] array) { array.Minus(divisor, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Minus(divisor, destination); return; } + if (units is double?[] array) { array.MinusCore(subtrahend.ToDouble(), count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).MinusCore(subtrahend.ToDouble(), count, destination); return; } int i = 0; - double invMinusisor = 1.0 / divisor.ToDouble(); + double invMinusisor = 1.0 / subtrahend.ToDouble(); foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value * invMinusisor).ToUnit() : null; + destination[i++] = ((item ?? 0d) * invMinusisor).ToUnit(); } - internal static void Minus(this T dividend, IReadOnlyCollection units, Span destination) + internal static void Minus(this T minuend, IReadOnlyCollection units, Span destination) where T : struct, IMensuraUnit, IEquatable { if (units is null) return; @@ -1196,14 +1181,15 @@ internal static partial class CollectionsMinusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is double[] array) { dividend.Minus(array, destination); return; } - if (units is List list) { dividend.Minus(CollectionsMarshal.AsSpan(list), destination); return; } + if (units is double[] array) { minuend.ToDouble().MinusCore(array, count, destination); return; } + if (units is List list) { minuend.ToDouble().MinusCore(CollectionsMarshal.AsSpan(list), count, destination); return; } int i = 0; + var div = minuend.ToDouble(); foreach (var item in units) - destination[i++] = (dividend.ToDouble() / item).ToUnit(); + destination[i++] = (div / item).ToUnit(); } - internal static void Minus(this T dividend, IReadOnlyCollection units, Span destination) + internal static void Minus(this T minuend, IReadOnlyCollection units, Span destination) where T : struct, IMensuraUnit, IEquatable { if (units is null) return; @@ -1212,100 +1198,98 @@ internal static partial class CollectionsMinusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is double?[] array) { dividend.Minus(array, destination); return; } - if (units is List list) { dividend.Minus(CollectionsMarshal.AsSpan(list), destination); return; } + if (units is double?[] array) { minuend.ToDouble().MinusCore(array, count, destination); return; } + if (units is List list) { minuend.ToDouble().MinusCore(CollectionsMarshal.AsSpan(list), count, destination); return; } int i = 0; + var div = minuend.ToDouble(); foreach (var item in units) - destination[i++] = item.HasValue - ? (dividend.ToDouble() / item.Value).ToUnit() : null; + destination[i++] = (div / (item ?? 0d)).ToUnit(); } // === IEnumerable + yeild === - static IEnumerable MinusideIterator(IEnumerable units, double divisor) + static IEnumerable MinusideIterator(IEnumerable units, double subtrahend) where T : struct, IMensuraUnit, IEquatable { - double invMinusisor = 1.0 / divisor; + double invMinusisor = 1.0 / subtrahend; foreach (var item in units) yield return (item * invMinusisor).ToUnit(); } - static IEnumerable MinusideNullableIterator(IEnumerable units, double divisor) + static IEnumerable MinusideNullableIterator(IEnumerable units, double subtrahend) where T : struct, IMensuraUnit, IEquatable { - double invMinusisor = 1.0 / divisor; + double invMinusisor = 1.0 / subtrahend; foreach (var item in units) - yield return item.HasValue - ? (item.Value * invMinusisor).ToUnit() : null; + yield return ((item ?? 0d) * invMinusisor).ToUnit(); } - static IEnumerable MinusideIterator(double dividend, IEnumerable units) + static IEnumerable MinusideIterator(double minuend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return (dividend / item).ToUnit(); + yield return (minuend / item).ToUnit(); } - static IEnumerable MinusideNullableIterator(double dividend, IEnumerable units) + static IEnumerable MinusideNullableIterator(double minuend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? (dividend / item.Value).ToUnit() : null; + yield return (minuend / (item ?? 0d)).ToUnit(); } // === IEnumerable === - internal static IEnumerable Minus(this IEnumerable units, T divisor) + internal static IEnumerable Minus(this IEnumerable units, T subtrahend) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - if (units is double[] array) return array.Minus(divisor); - if (units is List list) return list.Minus(divisor); + if (units is double[] array) return array.Minus(subtrahend); + if (units is List list) return list.Minus(subtrahend); if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.MinusCore(divisor.ToDouble(), arr.Length, arr); + arr.MinusCore(subtrahend.ToDouble(), arr.Length, arr); return arr.ReCast(); } - return MinusideIterator(units, divisor.ToDouble()); + return MinusideIterator(units, subtrahend.ToDouble()); } - internal static IEnumerable Minus(this IEnumerable units, T divisor) + internal static IEnumerable Minus(this IEnumerable units, T subtrahend) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - if (units is double?[] array) return array.Minus(divisor); - if (units is List list) return list.Minus(divisor); + if (units is double?[] array) return array.Minus(subtrahend); + if (units is List list) return list.Minus(subtrahend); if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.MinusCore(divisor.ToDouble(), arr.Length, arr); + arr.MinusCore(subtrahend.ToDouble(), arr.Length, arr); return arr.ReCast(); } - return MinusideNullableIterator(units, divisor.ToDouble()); + return MinusideNullableIterator(units, subtrahend.ToDouble()); } - internal static IEnumerable Minus(this T dividend, IEnumerable units) + internal static IEnumerable Minus(this T minuend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - if (units is double[] array) return dividend.Minus(array); - if (units is List list) return dividend.Minus(list); + if (units is double[] array) return minuend.Minus(array); + if (units is List list) return minuend.Minus(list); if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - dividend.ToDouble().MinusCore(arr, arr.Length, arr); + minuend.ToDouble().MinusCore(arr, arr.Length, arr); return arr.ReCast(); } - return MinusideIterator(dividend.ToDouble(), units); + return MinusideIterator(minuend.ToDouble(), units); } - internal static IEnumerable Minus(this T dividend, IEnumerable units) + internal static IEnumerable Minus(this T minuend, IEnumerable units) where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - if (units is double?[] array) return dividend.Minus(array); - if (units is List list) return dividend.Minus(list); + if (units is double?[] array) return minuend.Minus(array); + if (units is List list) return minuend.Minus(list); if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - dividend.ToDouble().MinusCore(arr, arr.Length, arr); + minuend.ToDouble().MinusCore(arr, arr.Length, arr); return arr.ReCast(); } - return MinusideNullableIterator(dividend.ToDouble(), units); + return MinusideNullableIterator(minuend.ToDouble(), units); } } \ No newline at end of file diff --git a/QWERTYkez.Mensura/Extensions/CollectionsMultiplyExtensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsMultiplyExtensions.cs index b21811f..e4d73f1 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsMultiplyExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsMultiplyExtensions.cs @@ -2,8 +2,8 @@ internal static partial class CollectionsMultiplyExtensions { - // === MultiplyCore === SIMD - internal static void MultiplyCore(this ReadOnlySpan units, double multiplicator, int len, Span destination) + // === MulCore === SIMD + internal static void MulCore(this ReadOnlySpan units, double multiplicator, int len, Span destination) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { @@ -35,7 +35,7 @@ internal static partial class CollectionsMultiplyExtensions Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * multiplicator; } } - internal static void MultiplyCore(this ReadOnlySpan units, double multiplicator, int len, Span destination) + internal static void MulCore(this ReadOnlySpan units, double multiplicator, int len, Span destination) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { @@ -61,10 +61,10 @@ internal static partial class CollectionsMultiplyExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (u0.Value.ToDouble() * multiplicator).ToUnit() : null; - d1 = u1.HasValue ? (u1.Value.ToDouble() * multiplicator).ToUnit() : null; - d2 = u2.HasValue ? (u2.Value.ToDouble() * multiplicator).ToUnit() : null; - d3 = u3.HasValue ? (u3.Value.ToDouble() * multiplicator).ToUnit() : null; + d0 = (u0.Protected() * multiplicator).ToUnit(); + d1 = (u1.Protected() * multiplicator).ToUnit(); + d2 = (u2.Protected() * multiplicator).ToUnit(); + d3 = (u3.Protected() * multiplicator).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -72,20 +72,19 @@ internal static partial class CollectionsMultiplyExtensions { T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? (unit.Value.ToDouble() * multiplicator).ToUnit() : null; + dst = (unit.Protected() * multiplicator).ToUnit(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void MultiplyCore(this double multiplicator, ReadOnlySpan units, int len, Span destination) + internal static void MulCore(this double multiplicator, ReadOnlySpan units, int len, Span destination) where T : struct, IMensuraUnit, IEquatable - where R : struct, IMensuraUnit, IEquatable => units.MultiplyCore(multiplicator, len, destination); + where R : struct, IMensuraUnit, IEquatable => units.MulCore(multiplicator, len, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void MultiplyCore(this double multiplicator, ReadOnlySpan units, int len, Span destination) + internal static void MulCore(this double multiplicator, ReadOnlySpan units, int len, Span destination) where T : struct, IMensuraUnit, IEquatable - where R : struct, IMensuraUnit, IEquatable => units.MultiplyCore(multiplicator, len, destination); + where R : struct, IMensuraUnit, IEquatable => units.MulCore(multiplicator, len, destination); @@ -100,7 +99,7 @@ internal static partial class CollectionsMultiplyExtensions if (len == 0) return []; var result = new R[len]; - units.MultiplyCore(multiplicator, len, result); + units.MulCore(multiplicator, len, result); return result; } internal static R?[] Mul(this T?[] units, double multiplicator) @@ -112,7 +111,7 @@ internal static partial class CollectionsMultiplyExtensions if (len == 0) return []; var result = new R?[len]; - units.MultiplyCore(multiplicator, len, result); + units.MulCore(multiplicator, len, result); return result; } @@ -135,9 +134,9 @@ internal static partial class CollectionsMultiplyExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - MultiplyCore(CollectionsMarshal.AsSpan(units), multiplicator, count, resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + MulCore(CollectionsMarshal.AsSpan(units), multiplicator, count, result); + return result.WrapAsList(); } internal static List Mul(this List units, double multiplicator) where T : struct, IMensuraUnit, IEquatable @@ -147,9 +146,9 @@ internal static partial class CollectionsMultiplyExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - MultiplyCore(CollectionsMarshal.AsSpan(units), multiplicator, count, resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + MulCore(CollectionsMarshal.AsSpan(units), multiplicator, count, result); + return result.WrapAsList(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -173,8 +172,8 @@ internal static partial class CollectionsMultiplyExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { MultiplyCore(array, multiplicator, count, destination); return; } - if (units is List list) { MultiplyCore(CollectionsMarshal.AsSpan(list), multiplicator, count, destination); return; } + if (units is T[] array) { MulCore(array, multiplicator, count, destination); return; } + if (units is List list) { MulCore(CollectionsMarshal.AsSpan(list), multiplicator, count, destination); return; } int i = 0; foreach (var item in units) @@ -190,13 +189,12 @@ internal static partial class CollectionsMultiplyExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { MultiplyCore(array, multiplicator, count, destination); return; } - if (units is List list) { MultiplyCore(CollectionsMarshal.AsSpan(list), multiplicator, count, destination); return; } + if (units is T?[] array) { MulCore(array, multiplicator, count, destination); return; } + if (units is List list) { MulCore(CollectionsMarshal.AsSpan(list), multiplicator, count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() * multiplicator).ToUnit() : null; + destination[i++] = (item.Protected() * multiplicator).ToUnit(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -222,8 +220,7 @@ internal static partial class CollectionsMultiplyExtensions where R : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() * multiplicator).ToUnit() : null; + yield return (item.Protected() * multiplicator).ToUnit(); } // === IEnumerable === @@ -237,7 +234,7 @@ internal static partial class CollectionsMultiplyExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Mul(multiplicator, arr); + arr.MulCore(multiplicator, arr.Length, arr); return arr.ReCast(); } return MultiplyIterator(units, multiplicator); @@ -252,7 +249,7 @@ internal static partial class CollectionsMultiplyExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Mul(multiplicator, arr); + arr.MulCore(multiplicator, arr.Length, arr); return arr.ReCast(); } return MultiplyNullableIterator(units, multiplicator); @@ -280,7 +277,7 @@ internal static partial class CollectionsMultiplyExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.MultiplyCore(multiplicator, len, destination); + units.MulCore(multiplicator, len, destination); } internal static void Mul(this ReadOnlySpan units, double multiplicator, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -290,7 +287,7 @@ internal static partial class CollectionsMultiplyExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.MultiplyCore(multiplicator, len, destination); + units.MulCore(multiplicator, len, destination); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -310,7 +307,7 @@ internal static partial class CollectionsMultiplyExtensions if (len == 0) return []; var result = new T[len]; - Mul(units, multiplicator, result); + units.MulCore(multiplicator, len, result); return result; } internal static T?[] Mul(this T?[] units, double multiplicator) @@ -321,7 +318,7 @@ internal static partial class CollectionsMultiplyExtensions if (len == 0) return []; var result = new T?[len]; - Mul(units, multiplicator, result); + units.MulCore(multiplicator, len, result); return result; } @@ -338,12 +335,12 @@ internal static partial class CollectionsMultiplyExtensions where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new T[len]; - Mul(CollectionsMarshal.AsSpan(units), multiplicator, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + CollectionsMarshal.AsSpan(units).MulCore(multiplicator, count, result); + return result.WrapAsList(); } internal static List Mul(this List units, double multiplicator) where T : struct, IMensuraUnit, IEquatable @@ -352,9 +349,9 @@ internal static partial class CollectionsMultiplyExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Mul(CollectionsMarshal.AsSpan(units), multiplicator, resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + CollectionsMarshal.AsSpan(units).MulCore(multiplicator, count, result); + return result.WrapAsList(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -375,8 +372,8 @@ internal static partial class CollectionsMultiplyExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { array.Mul(multiplicator, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Mul(multiplicator, destination); return; } + if (units is T[] array) { array.MulCore(multiplicator, array.Length, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).MulCore(multiplicator, list.Count, destination); return; } int i = 0; foreach (var item in units) @@ -391,13 +388,12 @@ internal static partial class CollectionsMultiplyExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.Mul(multiplicator, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Mul(multiplicator, destination); return; } + if (units is T?[] array) { array.MulCore(multiplicator, array.Length, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).MulCore(multiplicator, list.Count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() * multiplicator).ToUnit() : null; + destination[i++] = (item.Protected() * multiplicator).ToUnit(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -419,8 +415,7 @@ internal static partial class CollectionsMultiplyExtensions where T : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() * multiplicator).ToUnit() : null; + yield return (item.Protected() * multiplicator).ToUnit(); } // === IEnumerable === @@ -433,7 +428,7 @@ internal static partial class CollectionsMultiplyExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Mul(multiplicator, arr); + arr.MulCore(multiplicator, arr.Length, arr); return arr; } return MultiplyIterator(units, multiplicator); @@ -447,7 +442,7 @@ internal static partial class CollectionsMultiplyExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Mul(multiplicator, arr); + arr.MulCore(multiplicator, arr.Length, arr); return arr; } return MultiplyNullableIterator(units, multiplicator); @@ -469,8 +464,8 @@ internal static partial class CollectionsMultiplyExtensions - // === MultiplyCore === SIMD - internal static void MultiplyCore(this ReadOnlySpan srcDouble, double multiplicator, int len, Span destination) + // === MulCore === SIMD + internal static void MulCore(this ReadOnlySpan srcDouble, double multiplicator, int len, Span destination) where R : struct, IMensuraUnit, IEquatable { Span dstDouble = MemoryMarshal.Cast(destination); @@ -500,7 +495,7 @@ internal static partial class CollectionsMultiplyExtensions Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * multiplicator; } } - internal static void MultiplyCore(this ReadOnlySpan units, double multiplicator, int len, Span destination) + internal static void MulCore(this ReadOnlySpan units, double multiplicator, int len, Span destination) where R : struct, IMensuraUnit, IEquatable { // Получаем прямые неуправляемые ref-ссылки на начало буферов за 0 тактов @@ -525,10 +520,10 @@ internal static partial class CollectionsMultiplyExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (u0.Value * multiplicator).ToUnit() : null; - d1 = u1.HasValue ? (u1.Value * multiplicator).ToUnit() : null; - d2 = u2.HasValue ? (u2.Value * multiplicator).ToUnit() : null; - d3 = u3.HasValue ? (u3.Value * multiplicator).ToUnit() : null; + d0 = ((u0 ?? 0d) * multiplicator).ToUnit(); + d1 = ((u1 ?? 0d) * multiplicator).ToUnit(); + d2 = ((u2 ?? 0d) * multiplicator).ToUnit(); + d3 = ((u3 ?? 0d) * multiplicator).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -537,18 +532,18 @@ internal static partial class CollectionsMultiplyExtensions var unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - dst = unit.HasValue ? (unit.Value * multiplicator).ToUnit() : null; + dst = ((unit ?? 0d) * multiplicator).ToUnit(); } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MultiplyCore(this double multiplicator, ReadOnlySpan units, - int len, Span destination) where R : struct, IMensuraUnit, IEquatable => units.MultiplyCore(multiplicator, len, destination); - [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MultiplyCore(this double multiplicator, ReadOnlySpan units, - int len, Span destination) where R : struct, IMensuraUnit, IEquatable => units.MultiplyCore(multiplicator, len, destination); + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MulCore(this double multiplicator, ReadOnlySpan units, + int len, Span destination) where R : struct, IMensuraUnit, IEquatable => units.MulCore(multiplicator, len, destination); + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MulCore(this double multiplicator, ReadOnlySpan units, + int len, Span destination) where R : struct, IMensuraUnit, IEquatable => units.MulCore(multiplicator, len, destination); - // === MultiplyCore === SIMD - internal static void MultiplyCore(this ReadOnlySpan srcDouble, double multiplicator, int len, Span dstDouble) + // === MulCore === SIMD + internal static void MulCore(this ReadOnlySpan srcDouble, double multiplicator, int len, Span dstDouble) { var vectorizedMultiplicator = new Vector(multiplicator); int vectorSize = Vector.Count; @@ -575,7 +570,7 @@ internal static partial class CollectionsMultiplyExtensions Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * multiplicator; } } - internal static void MultiplyCore(this ReadOnlySpan units, double multiplicator, int len, Span destination) + internal static void MulCore(this ReadOnlySpan units, double multiplicator, int len, Span destination) { // Получаем прямые неуправляемые ref-ссылки на начало буферов за 0 тактов ref var srcRef = ref MemoryMarshal.GetReference(units); @@ -599,10 +594,10 @@ internal static partial class CollectionsMultiplyExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? u0.Value * multiplicator : null; - d1 = u1.HasValue ? u1.Value * multiplicator : null; - d2 = u2.HasValue ? u2.Value * multiplicator : null; - d3 = u3.HasValue ? u3.Value * multiplicator : null; + d0 = (u0 ?? 0d) * multiplicator; + d1 = (u1 ?? 0d) * multiplicator; + d2 = (u2 ?? 0d) * multiplicator; + d3 = (u3 ?? 0d) * multiplicator; } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -610,15 +605,14 @@ internal static partial class CollectionsMultiplyExtensions { var unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? unit.Value * multiplicator : null; + dst = (unit ?? 0d) * multiplicator; } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MultiplyCore(this double multiplicator, - ReadOnlySpan units, int len, Span destination) => units.MultiplyCore(multiplicator, len, destination); - [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MultiplyCore(this double multiplicator, - ReadOnlySpan units, int len, Span destination) => units.MultiplyCore(multiplicator, len, destination); + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MulCore(this double multiplicator, + ReadOnlySpan units, int len, Span destination) => units.MulCore(multiplicator, len, destination); + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MulCore(this double multiplicator, + ReadOnlySpan units, int len, Span destination) => units.MulCore(multiplicator, len, destination); @@ -633,7 +627,7 @@ internal static partial class CollectionsMultiplyExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.MultiplyCore(multiplicator.ToDouble(), len, destination); + units.MulCore(multiplicator.ToDouble(), len, destination); } internal static void Mul(this ReadOnlySpan units, T multiplicator, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -643,7 +637,7 @@ internal static partial class CollectionsMultiplyExtensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.MultiplyCore(multiplicator.ToDouble(), len, destination); + units.MulCore(multiplicator.ToDouble(), len, destination); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -663,7 +657,7 @@ internal static partial class CollectionsMultiplyExtensions if (len == 0) return []; var result = new T[len]; - Mul(units, multiplicator, result); + units.MulCore(multiplicator.ToDouble(), len, result); return result; } internal static T?[] Mul(this double?[] units, T multiplicator) @@ -674,7 +668,7 @@ internal static partial class CollectionsMultiplyExtensions if (len == 0) return []; var result = new T?[len]; - Mul(units, multiplicator, result); + units.MulCore(multiplicator.ToDouble(), len, result); return result; } @@ -691,12 +685,12 @@ internal static partial class CollectionsMultiplyExtensions where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new T[len]; - Mul(CollectionsMarshal.AsSpan(units), multiplicator, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + CollectionsMarshal.AsSpan(units).MulCore(multiplicator.ToDouble(), count, result); + return result.WrapAsList(); } internal static List Mul(this List units, T multiplicator) where T : struct, IMensuraUnit, IEquatable @@ -705,9 +699,9 @@ internal static partial class CollectionsMultiplyExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Mul(CollectionsMarshal.AsSpan(units), multiplicator, resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + CollectionsMarshal.AsSpan(units).MulCore(multiplicator.ToDouble(), count, result); + return result.WrapAsList(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -728,12 +722,13 @@ internal static partial class CollectionsMultiplyExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is double[] array) { array.MultiplyCore(multiplicator.ToDouble(), array.Length, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).MultiplyCore(multiplicator.ToDouble(), list.Count, destination); return; } + if (units is double[] array) { array.MulCore(multiplicator.ToDouble(), array.Length, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).MulCore(multiplicator.ToDouble(), list.Count, destination); return; } int i = 0; + var mul = multiplicator.ToDouble(); foreach (var item in units) - destination[i++] = (item * multiplicator.ToDouble()).ToUnit(); + destination[i++] = (item * mul).ToUnit(); } internal static void Mul(this IReadOnlyCollection units, T multiplicator, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -744,13 +739,13 @@ internal static partial class CollectionsMultiplyExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is double?[] array) { array.MultiplyCore(multiplicator.ToDouble(), array.Length, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).MultiplyCore(multiplicator.ToDouble(), list.Count, destination); return; } + if (units is double?[] array) { array.MulCore(multiplicator.ToDouble(), array.Length, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).MulCore(multiplicator.ToDouble(), list.Count, destination); return; } int i = 0; + var mul = multiplicator.ToDouble(); foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value * multiplicator.ToDouble()).ToUnit() : null; + destination[i++] = ((item ?? 0d) * mul).ToUnit(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -772,8 +767,7 @@ internal static partial class CollectionsMultiplyExtensions where T : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? (item.Value * multiplicator).ToUnit() : null; + yield return ((item ?? 0d) * multiplicator).ToUnit(); } // === IEnumerable === @@ -786,7 +780,7 @@ internal static partial class CollectionsMultiplyExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.MultiplyCore(multiplicator.ToDouble(), arr.Length, arr); + arr.MulCore(multiplicator.ToDouble(), arr.Length, arr); return arr.ReCast(); } return MultiplyIterator(units, multiplicator.ToDouble()); @@ -800,7 +794,7 @@ internal static partial class CollectionsMultiplyExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.MultiplyCore(multiplicator.ToDouble(), arr.Length, arr); + arr.MulCore(multiplicator.ToDouble(), arr.Length, arr); return arr.ReCast(); } return MultiplyNullableIterator(units, multiplicator.ToDouble()); diff --git a/QWERTYkez.Mensura/Extensions/CollectionsPlusExtensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsPlusExtensions.cs index 68d9a70..3565597 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsPlusExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsPlusExtensions.cs @@ -62,10 +62,10 @@ internal static partial class CollectionsPlusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (u0.Value.ToDouble() + summand).ToUnit() : null; - d1 = u1.HasValue ? (u1.Value.ToDouble() + summand).ToUnit() : null; - d2 = u2.HasValue ? (u2.Value.ToDouble() + summand).ToUnit() : null; - d3 = u3.HasValue ? (u3.Value.ToDouble() + summand).ToUnit() : null; + d0 = (u0.Protected() + summand).ToUnit(); + d1 = (u1.Protected() + summand).ToUnit(); + d2 = (u2.Protected() + summand).ToUnit(); + d3 = (u3.Protected() + summand).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -73,8 +73,7 @@ internal static partial class CollectionsPlusExtensions { T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? (unit.Value.ToDouble() + summand).ToUnit() : null; + dst = (unit.Protected() + summand).ToUnit(); } } @@ -136,9 +135,9 @@ internal static partial class CollectionsPlusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - PlusCore(CollectionsMarshal.AsSpan(units), summand, count, resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + PlusCore(CollectionsMarshal.AsSpan(units), summand, count, result); + return result.WrapAsList(); } internal static List Plus(this List units, double summand) where T : struct, IMensuraUnit, IEquatable @@ -148,9 +147,9 @@ internal static partial class CollectionsPlusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - PlusCore(CollectionsMarshal.AsSpan(units), summand, count, resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + PlusCore(CollectionsMarshal.AsSpan(units), summand, count, result); + return result.WrapAsList(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -196,8 +195,7 @@ internal static partial class CollectionsPlusExtensions int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() + summand).ToUnit() : null; + destination[i++] = (item.Protected() + summand).ToUnit(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -223,8 +221,7 @@ internal static partial class CollectionsPlusExtensions where R : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() + summand).ToUnit() : null; + yield return (item.Protected() + summand).ToUnit(); } // === IEnumerable === @@ -238,7 +235,7 @@ internal static partial class CollectionsPlusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Plus(summand, arr); + arr.PlusCore(summand, arr.Length, arr); return arr.ReCast(); } return PlusIterator(units, summand); @@ -253,7 +250,7 @@ internal static partial class CollectionsPlusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Plus(summand, arr); + arr.PlusCore(summand, arr.Length, arr); return arr.ReCast(); } return PlusNullableIterator(units, summand); @@ -311,7 +308,7 @@ internal static partial class CollectionsPlusExtensions if (len == 0) return []; var result = new T[len]; - Plus(units, summand, result); + units.PlusCore(summand, len, result); return result; } internal static T?[] Plus(this T?[] units, double summand) @@ -322,7 +319,7 @@ internal static partial class CollectionsPlusExtensions if (len == 0) return []; var result = new T?[len]; - Plus(units, summand, result); + PlusCore(units, summand, len, result); return result; } @@ -339,12 +336,12 @@ internal static partial class CollectionsPlusExtensions where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new T[len]; - Plus(CollectionsMarshal.AsSpan(units), summand, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + CollectionsMarshal.AsSpan(units).PlusCore(summand, count, result); + return result.WrapAsList(); } internal static List Plus(this List units, double summand) where T : struct, IMensuraUnit, IEquatable @@ -353,9 +350,9 @@ internal static partial class CollectionsPlusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Plus(CollectionsMarshal.AsSpan(units), summand, resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + CollectionsMarshal.AsSpan(units).PlusCore(summand, count, result); + return result.WrapAsList(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -376,8 +373,8 @@ internal static partial class CollectionsPlusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { array.Plus(summand, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Plus(summand, destination); return; } + if (units is T[] array) { array.PlusCore(summand, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).PlusCore(summand, count, destination); return; } int i = 0; foreach (var item in units) @@ -392,13 +389,12 @@ internal static partial class CollectionsPlusExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.Plus(summand, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Plus(summand, destination); return; } + if (units is T?[] array) { array.PlusCore(summand, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).PlusCore(summand, count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() + summand).ToUnit() : null; + destination[i++] = (item.Protected() + summand).ToUnit(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -420,8 +416,7 @@ internal static partial class CollectionsPlusExtensions where T : struct, IMensuraUnit, IEquatable { foreach (T? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() + summand).ToUnit() : null; + yield return (item.Protected() + summand).ToUnit(); } // === IEnumerable === @@ -434,7 +429,7 @@ internal static partial class CollectionsPlusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Plus(summand, arr); + arr.PlusCore(summand, arr.Length, arr); return arr; } return PlusIterator(units, summand); @@ -448,7 +443,7 @@ internal static partial class CollectionsPlusExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Plus(summand, arr); + arr.PlusCore(summand, arr.Length, arr); return arr; } return PlusNullableIterator(units, summand); @@ -526,10 +521,10 @@ internal static partial class CollectionsPlusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? (u0.Value + summand).ToUnit() : null; - d1 = u1.HasValue ? (u1.Value + summand).ToUnit() : null; - d2 = u2.HasValue ? (u2.Value + summand).ToUnit() : null; - d3 = u3.HasValue ? (u3.Value + summand).ToUnit() : null; + d0 = ((u0 ?? 0d) + summand).ToUnit(); + d1 = ((u1 ?? 0d) + summand).ToUnit(); + d2 = ((u2 ?? 0d) + summand).ToUnit(); + d3 = ((u3 ?? 0d) + summand).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -537,8 +532,7 @@ internal static partial class CollectionsPlusExtensions { var unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? (unit.Value + summand).ToUnit() : null; + dst = ((unit ?? 0d) + summand).ToUnit(); } } @@ -602,10 +596,10 @@ internal static partial class CollectionsPlusExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага) - d0 = u0.HasValue ? u0.Value + summand : null; - d1 = u1.HasValue ? u1.Value + summand : null; - d2 = u2.HasValue ? u2.Value + summand : null; - d3 = u3.HasValue ? u3.Value + summand : null; + d0 = (u0 ?? 0d) + summand; + d1 = (u1 ?? 0d) + summand; + d2 = (u2 ?? 0d) + summand; + d3 = (u3 ?? 0d) + summand; } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук) @@ -613,8 +607,7 @@ internal static partial class CollectionsPlusExtensions { var unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - - dst = unit.HasValue ? unit.Value + summand : null; + dst = (unit ?? 0d) + summand; } } @@ -668,7 +661,7 @@ internal static partial class CollectionsPlusExtensions if (len == 0) return []; var result = new T[len]; - Plus(units, summand, result); + units.PlusCore(summand.ToDouble(), len, result); return result; } internal static T?[] Plus(this double?[] units, T summand) @@ -679,7 +672,7 @@ internal static partial class CollectionsPlusExtensions if (len == 0) return []; var result = new T?[len]; - Plus(units, summand, result); + units.PlusCore(summand.ToDouble(), len, result); return result; } @@ -696,12 +689,12 @@ internal static partial class CollectionsPlusExtensions where T : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new T[len]; - Plus(CollectionsMarshal.AsSpan(units), summand, resultArray); - return resultArray.WrapAsList(); + var result = new T[count]; + CollectionsMarshal.AsSpan(units).PlusCore(summand.ToDouble(), count, result); + return result.WrapAsList(); } internal static List Plus(this List units, T summand) where T : struct, IMensuraUnit, IEquatable @@ -710,9 +703,9 @@ internal static partial class CollectionsPlusExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new T?[count]; - Plus(CollectionsMarshal.AsSpan(units), summand, resultArray); - return resultArray.WrapAsList(); + var result = new T?[count]; + CollectionsMarshal.AsSpan(units).PlusCore(summand.ToDouble(), count, result); + return result.WrapAsList(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -737,8 +730,9 @@ internal static partial class CollectionsPlusExtensions if (units is List list) { CollectionsMarshal.AsSpan(list).PlusCore(summand.ToDouble(), list.Count, destination); return; } int i = 0; + var sum = summand.ToDouble(); foreach (var item in units) - destination[i++] = (item + summand.ToDouble()).ToUnit(); + destination[i++] = (item + sum).ToUnit(); } internal static void Plus(this IReadOnlyCollection units, T summand, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -753,9 +747,9 @@ internal static partial class CollectionsPlusExtensions if (units is List list) { CollectionsMarshal.AsSpan(list).PlusCore(summand.ToDouble(), list.Count, destination); return; } int i = 0; + var sum = summand.ToDouble(); foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value + summand.ToDouble()).ToUnit() : null; + destination[i++] = ((item ?? 0d) + sum).ToUnit(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -777,8 +771,7 @@ internal static partial class CollectionsPlusExtensions where T : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? (item.Value + summand).ToUnit() : null; + yield return ((item ?? 0d) + summand).ToUnit(); } // === IEnumerable === diff --git a/QWERTYkez.Mensura/Extensions/CollectionsPow2Extensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsPow2Extensions.cs index 45e19c6..035496f 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsPow2Extensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsPow2Extensions.cs @@ -130,7 +130,7 @@ internal static partial class CollectionsPow2Extensions if (len == 0) return []; var result = new R[len]; - Pow2(units, result); + units.Pow2Core(len, result); return result; } internal static R?[] Pow2(this T?[] units) @@ -142,7 +142,7 @@ internal static partial class CollectionsPow2Extensions if (len == 0) return []; var result = new R?[len]; - Pow2(units, result); + units.Pow2Core(len, result); return result; } @@ -155,9 +155,9 @@ internal static partial class CollectionsPow2Extensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - Pow2(CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + CollectionsMarshal.AsSpan(units).Pow2Core(count, result); + return result.WrapAsList(); } internal static List Pow2(this List units) where T : struct, IMensuraUnit, IEquatable @@ -167,9 +167,9 @@ internal static partial class CollectionsPow2Extensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - Pow2(CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + CollectionsMarshal.AsSpan(units).Pow2Core(count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -183,8 +183,8 @@ internal static partial class CollectionsPow2Extensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { array.Pow2(destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Pow2(destination); return; } + if (units is T[] array) { array.Pow2Core(count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).Pow2Core(count, destination); return; } int i = 0; foreach (var item in units) @@ -200,13 +200,12 @@ internal static partial class CollectionsPow2Extensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.Pow2(destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Pow2(destination); return; } + if (units is T?[] array) { array.Pow2Core(count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).Pow2Core(count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? item.Value.ToDouble().QuickPow2().ToUnit() : null; + destination[i++] = item.Protected().QuickPow2().ToUnit(); } // === IEnumerable + yeild === @@ -222,8 +221,7 @@ internal static partial class CollectionsPow2Extensions where R : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? item.Value.ToDouble().QuickPow2().ToUnit() : null; + yield return item.Protected().QuickPow2().ToUnit(); } // === IEnumerable === @@ -237,7 +235,7 @@ internal static partial class CollectionsPow2Extensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Pow2(arr); + arr.Pow2Core(arr.Length, arr); return arr.ReCast(); } else return Pow2Iterator(units); @@ -252,7 +250,7 @@ internal static partial class CollectionsPow2Extensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Pow2(arr); + arr.Pow2Core(arr.Length, arr); return arr.ReCast(); } else return Pow2NullableIterator(units); diff --git a/QWERTYkez.Mensura/Extensions/CollectionsPow3Extensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsPow3Extensions.cs index 7193ef4..69b1f74 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsPow3Extensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsPow3Extensions.cs @@ -1,7 +1,4 @@ -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace QWERTYkez.Mensura.Extensions; +namespace QWERTYkez.Mensura.Extensions; internal static partial class CollectionsPow3Extensions { @@ -10,8 +7,8 @@ internal static partial class CollectionsPow3Extensions // === ТРЕТЬЯ СТЕПЕНЬ ========================================== - // === PowCore3 === SIMD - internal static void PowCore3(this ReadOnlySpan units, int len, Span destination) + // === Pow3Core === SIMD + internal static void Pow3Core(this ReadOnlySpan units, int len, Span destination) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { @@ -46,7 +43,7 @@ internal static partial class CollectionsPow3Extensions dstDouble[i] = val * val * val; } } - internal static void PowCore3(this ReadOnlySpan units, int len, Span destination) + internal static void Pow3Core(this ReadOnlySpan units, int len, Span destination) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { @@ -109,7 +106,7 @@ internal static partial class CollectionsPow3Extensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.PowCore3(len, destination); + units.Pow3Core(len, destination); } internal static void Pow3(this ReadOnlySpan units, Span destination) where T : struct, IMensuraUnit, IEquatable @@ -120,7 +117,7 @@ internal static partial class CollectionsPow3Extensions if (len > destination.Length) throw new ArgumentException("Целевой буфер destination меньше исходного source."); - units.PowCore3(len, destination); + units.Pow3Core(len, destination); } // === Array === @@ -133,7 +130,7 @@ internal static partial class CollectionsPow3Extensions if (len == 0) return []; var result = new R[len]; - Pow3(units, result); + units.Pow3Core(len, result); return result; } internal static R?[] Pow3(this T?[] units) @@ -145,7 +142,7 @@ internal static partial class CollectionsPow3Extensions if (len == 0) return []; var result = new R?[len]; - Pow3(units, result); + units.Pow3Core(len, result); return result; } @@ -158,9 +155,9 @@ internal static partial class CollectionsPow3Extensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - Pow3(CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + CollectionsMarshal.AsSpan(units).Pow3Core(count, result); + return result.WrapAsList(); } internal static List Pow3(this List units) where T : struct, IMensuraUnit, IEquatable @@ -170,9 +167,9 @@ internal static partial class CollectionsPow3Extensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - Pow3(CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + CollectionsMarshal.AsSpan(units).Pow3Core(count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -186,8 +183,8 @@ internal static partial class CollectionsPow3Extensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { array.Pow3(destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Pow3(destination); return; } + if (units is T[] array) { array.Pow3Core(count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).Pow3Core(count, destination); return; } int i = 0; foreach (var item in units) @@ -203,13 +200,12 @@ internal static partial class CollectionsPow3Extensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.Pow3(destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Pow3(destination); return; } + if (units is T?[] array) { array.Pow3Core(count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).Pow3Core(count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? item.Value.ToDouble().QuickPow3().ToUnit() : null; + destination[i++] = item.Protected().QuickPow3().ToUnit(); } // === IEnumerable + yeild === @@ -225,8 +221,7 @@ internal static partial class CollectionsPow3Extensions where R : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? item.Value.ToDouble().QuickPow3().ToUnit() : null; + yield return item.Protected().QuickPow3().ToUnit(); } // === IEnumerable === @@ -240,7 +235,7 @@ internal static partial class CollectionsPow3Extensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Pow3(arr); + arr.Pow3Core(arr.Length, arr); return arr.ReCast(); } else return PowIterator3(units); @@ -255,7 +250,7 @@ internal static partial class CollectionsPow3Extensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Pow3(arr); + arr.Pow3Core(arr.Length, arr); return arr.ReCast(); } else return PowNullableIterator3(units); diff --git a/QWERTYkez.Mensura/Extensions/CollectionsPowNExtensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsPowNExtensions.cs index 409b6d6..234e4cf 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsPowNExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsPowNExtensions.cs @@ -129,10 +129,10 @@ internal static partial class CollectionsPowNExtensions ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); // Выполняем быструю бинарную математику и трансформируем тип из T в R по месту - d0 = u0.HasValue ? u0.Value.ToDouble().QuickPow(power).ToUnit() : null; - d1 = u1.HasValue ? u1.Value.ToDouble().QuickPow(power).ToUnit() : null; - d2 = u2.HasValue ? u2.Value.ToDouble().QuickPow(power).ToUnit() : null; - d3 = u3.HasValue ? u3.Value.ToDouble().QuickPow(power).ToUnit() : null; + d0 = u0.Protected().QuickPow(power).ToUnit(); + d1 = u1.Protected().QuickPow(power).ToUnit(); + d2 = u2.Protected().QuickPow(power).ToUnit(); + d3 = u3.Protected().QuickPow(power).ToUnit(); } // 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 шчку) @@ -141,7 +141,7 @@ internal static partial class CollectionsPowNExtensions T? unit = Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - dst = unit.HasValue ? unit.Value.ToDouble().QuickPow(power).ToUnit() : null; + dst = unit.Protected().QuickPow(power).ToUnit(); } } @@ -180,7 +180,7 @@ internal static partial class CollectionsPowNExtensions if (len == 0) return []; var result = new R[len]; - Pow(units, power, result); + units.PowCore(power, len, result); return result; } internal static R?[] Pow(this T?[] units, int power) @@ -192,7 +192,7 @@ internal static partial class CollectionsPowNExtensions if (len == 0) return []; var result = new R?[len]; - Pow(units, power, result); + units.PowCore(power, len, result); return result; } @@ -205,9 +205,9 @@ internal static partial class CollectionsPowNExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R[count]; - Pow(CollectionsMarshal.AsSpan(units), power, resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + CollectionsMarshal.AsSpan(units).PowCore(power, count, result); + return result.WrapAsList(); } internal static List Pow(this List units, int power) where T : struct, IMensuraUnit, IEquatable @@ -217,9 +217,9 @@ internal static partial class CollectionsPowNExtensions int count = units.Count; if (count == 0) return []; - var resultArray = new R?[count]; - Pow(CollectionsMarshal.AsSpan(units), power, resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + CollectionsMarshal.AsSpan(units).PowCore(power, count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -233,8 +233,8 @@ internal static partial class CollectionsPowNExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { array.Pow(power, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Pow(power, destination); return; } + if (units is T[] array) { array.PowCore(power, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).PowCore(power, count, destination); return; } int i = 0; foreach (var item in units) @@ -250,13 +250,12 @@ internal static partial class CollectionsPowNExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.Pow(power, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Pow(power, destination); return; } + if (units is T?[] array) { array.PowCore(power, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).PowCore(power, count, destination); return; } int i = 0; foreach (var item in units) - destination[i++] = item.HasValue - ? item.Value.ToDouble().QuickPow(power).ToUnit() : null; + destination[i++] = item.Protected().QuickPow(power).ToUnit(); } // === IEnumerable + yeild === @@ -272,8 +271,7 @@ internal static partial class CollectionsPowNExtensions where R : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? item.Value.ToDouble().QuickPow(power).ToUnit() : null; + yield return item.Protected().QuickPow(power).ToUnit(); } // === IEnumerable === @@ -287,7 +285,7 @@ internal static partial class CollectionsPowNExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Pow(power, arr); + arr.PowCore(power, arr.Length, arr); return arr.ReCast(); } else return PowIterator(units, power); @@ -302,7 +300,7 @@ internal static partial class CollectionsPowNExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Pow(power, arr); + arr.PowCore(power, arr.Length, arr); return arr.ReCast(); } else return PowNullableIterator(units, power); @@ -402,7 +400,7 @@ internal static partial class CollectionsPowNExtensions { // Прямая ref-запись в переданный снаружи destination ref var dst = ref destination[i]; - dst = Math.Pow(item.Value.ToDouble(), power).ToUnit(); + dst = Math.Pow(item.Protected(), power).ToUnit(); } } } @@ -443,7 +441,7 @@ internal static partial class CollectionsPowNExtensions if (len == 0) return []; var result = new R[len]; - units.Pow(power, result); + units.PowCore(power, len, result); return result; } internal static R?[] Pow(this T?[] units, double power) @@ -455,7 +453,7 @@ internal static partial class CollectionsPowNExtensions if (len == 0) return []; var result = new R?[len]; - units.Pow(power, result); + units.PowCore(power, len, result); return result; } @@ -465,11 +463,11 @@ internal static partial class CollectionsPowNExtensions where R : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var result = new R[len]; - CollectionsMarshal.AsSpan(units).Pow(power, result); + var result = new R[count]; + CollectionsMarshal.AsSpan(units).PowCore(power, count, result); return result.WrapAsList(); } internal static List Pow(this List units, double power) @@ -477,11 +475,11 @@ internal static partial class CollectionsPowNExtensions where R : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var result = new R?[len]; - CollectionsMarshal.AsSpan(units).Pow(power, result); + var result = new R?[count]; + CollectionsMarshal.AsSpan(units).PowCore(power, count, result); return result.WrapAsList(); } @@ -496,8 +494,8 @@ internal static partial class CollectionsPowNExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T[] array) { array.Pow(power, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Pow(power, destination); return; } + if (units is T[] array) { array.PowCore(power, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).PowCore(power, count, destination); return; } int i = 0; foreach (T item in units) @@ -513,13 +511,12 @@ internal static partial class CollectionsPowNExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.Pow(power, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Pow(power, destination); return; } + if (units is T?[] array) { array.PowCore(power, count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).PowCore(power, count, destination); return; } int i = 0; foreach (T? item in units) - destination[i++] = item.HasValue - ? Math.Pow(item.Value.ToDouble(), power).ToUnit() : null; + destination[i++] = Math.Pow(item.Protected(), power).ToUnit(); } // === IEnumerable + yield === @@ -535,8 +532,7 @@ internal static partial class CollectionsPowNExtensions where R : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? Math.Pow(item.Value.ToDouble(), power).ToUnit() : null; + yield return Math.Pow(item.Protected(), power).ToUnit(); } // === IEnumerable === @@ -550,7 +546,7 @@ internal static partial class CollectionsPowNExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Pow(power, arr); + arr.PowCore(power, arr.Length, arr); return arr.ReCast(); } else return PowIterator(units, power); @@ -565,7 +561,7 @@ internal static partial class CollectionsPowNExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Pow(power, arr); + arr.PowCore(power, arr.Length, arr); return arr.ReCast(); } else return PowNullableIterator(units, power); diff --git a/QWERTYkez.Mensura/Extensions/CollectionsRootOfCubeExtensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsRootOfCubeExtensions.cs index 55e5a25..e46017a 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsRootOfCubeExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsRootOfCubeExtensions.cs @@ -46,13 +46,13 @@ internal static partial class CollectionsRootOfCubeExtensions for (; i < unrollEnd; i += 4) { - Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i).HasValue ? Math.Sqrt(Unsafe.Add(ref srcRef, i)!.Value.ToDouble()).ToUnit() : null; - Unsafe.Add(ref dstRef, i + 1) = Unsafe.Add(ref srcRef, i + 1).HasValue ? Math.Sqrt(Unsafe.Add(ref srcRef, i + 1)!.Value.ToDouble()).ToUnit() : null; - Unsafe.Add(ref dstRef, i + 2) = Unsafe.Add(ref srcRef, i + 2).HasValue ? Math.Sqrt(Unsafe.Add(ref srcRef, i + 2)!.Value.ToDouble()).ToUnit() : null; - Unsafe.Add(ref dstRef, i + 3) = Unsafe.Add(ref srcRef, i + 3).HasValue ? Math.Sqrt(Unsafe.Add(ref srcRef, i + 3)!.Value.ToDouble()).ToUnit() : null; + Unsafe.Add(ref dstRef, i) = Math.Sqrt(Unsafe.Add(ref srcRef, i)!.Protected()).ToUnit(); + Unsafe.Add(ref dstRef, i + 1) = Math.Sqrt(Unsafe.Add(ref srcRef, i + 1)!.Protected()).ToUnit(); + Unsafe.Add(ref dstRef, i + 2) = Math.Sqrt(Unsafe.Add(ref srcRef, i + 2)!.Protected()).ToUnit(); + Unsafe.Add(ref dstRef, i + 3) = Math.Sqrt(Unsafe.Add(ref srcRef, i + 3)!.Protected()).ToUnit(); } for (; i < len; i++) - Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i).HasValue ? Math.Sqrt(Unsafe.Add(ref srcRef, i)!.Value.ToDouble()).ToUnit() : null; + Unsafe.Add(ref dstRef, i) = Math.Sqrt(Unsafe.Add(ref srcRef, i)!.Protected()).ToUnit(); } // === ReadOnlySpan === @@ -85,10 +85,11 @@ internal static partial class CollectionsRootOfCubeExtensions where R : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - if (units.Length == 0) return []; + var len = units.Length; + if (len == 0) return []; - var result = new R[units.Length]; - Cbrt(units, result); + var result = new R[len]; + units.CbrtCore(len, result); return result; } internal static R?[] Cbrt(this T?[] units) @@ -96,10 +97,11 @@ internal static partial class CollectionsRootOfCubeExtensions where R : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - if (units.Length == 0) return []; + var len = units.Length; + if (len == 0) return []; - var result = new R?[units.Length]; - Cbrt(units, result); + var result = new R?[len]; + units.CbrtCore(len, result); return result; } @@ -109,24 +111,24 @@ internal static partial class CollectionsRootOfCubeExtensions where R : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new R[len]; - Cbrt(CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new R[count]; + CollectionsMarshal.AsSpan(units).CbrtCore(count, result); + return result.WrapAsList(); } internal static List Cbrt(this List units) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new R?[len]; - Cbrt(CollectionsMarshal.AsSpan(units), resultArray); - return resultArray.WrapAsList(); + var result = new R?[count]; + CollectionsMarshal.AsSpan(units).CbrtCore(count, result); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -156,13 +158,12 @@ internal static partial class CollectionsRootOfCubeExtensions if (destination.Length < count) throw new ArgumentException("Destination too short"); - if (units is T?[] array) { array.Cbrt(destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Cbrt(destination); return; } + if (units is T?[] array) { array.CbrtCore(count, destination); return; } + if (units is List list) { CollectionsMarshal.AsSpan(list).CbrtCore(count, destination); return; } int i = 0; foreach (T? item in units) - destination[i++] = item.HasValue - ? Math.Sqrt(item.Value.ToDouble()).ToUnit() : null; + destination[i++] = Math.Sqrt(item.Protected()).ToUnit(); } // === IEnumerable + yield === @@ -177,8 +178,7 @@ internal static partial class CollectionsRootOfCubeExtensions where R : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? Math.Sqrt(item.Value.ToDouble()).ToUnit() : null; + yield return Math.Sqrt(item.Protected()).ToUnit(); } // === IEnumerable === @@ -192,7 +192,7 @@ internal static partial class CollectionsRootOfCubeExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Cbrt(arr); + arr.CbrtCore(arr.Length, arr); return arr.ReCast(); } else return SqrtIterator3(units); @@ -207,7 +207,7 @@ internal static partial class CollectionsRootOfCubeExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Cbrt(arr); + arr.CbrtCore(arr.Length, arr); return arr.ReCast(); } else return SqrtNullableIterator3(units); diff --git a/QWERTYkez.Mensura/Extensions/CollectionsRootOfSquareExtensions.cs b/QWERTYkez.Mensura/Extensions/CollectionsRootOfSquareExtensions.cs index 9937442..a525e09 100644 --- a/QWERTYkez.Mensura/Extensions/CollectionsRootOfSquareExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/CollectionsRootOfSquareExtensions.cs @@ -77,10 +77,10 @@ internal static partial class CollectionsRootOfSquareExtensions ref var d2 = ref Unsafe.Add(ref dstRef, i + 2); ref var d3 = ref Unsafe.Add(ref dstRef, i + 3); - d0 = u0.HasValue ? Math.Sqrt(u0.Value.ToDouble()).ToUnit() : null; - d1 = u1.HasValue ? Math.Sqrt(u1.Value.ToDouble()).ToUnit() : null; - d2 = u2.HasValue ? Math.Sqrt(u2.Value.ToDouble()).ToUnit() : null; - d3 = u3.HasValue ? Math.Sqrt(u3.Value.ToDouble()).ToUnit() : null; + d0 = Math.Sqrt(u0.Protected()).ToUnit(); + d1 = Math.Sqrt(u1.Protected()).ToUnit(); + d2 = Math.Sqrt(u2.Protected()).ToUnit(); + d3 = Math.Sqrt(u3.Protected()).ToUnit(); } // ХВОСТ ЦИКЛА: Остаток элементов @@ -88,7 +88,7 @@ internal static partial class CollectionsRootOfSquareExtensions { ref readonly T? unit = ref Unsafe.Add(ref srcRef, i); ref var dst = ref Unsafe.Add(ref dstRef, i); - dst = unit.HasValue ? Math.Sqrt(unit.Value.ToDouble()).ToUnit() : null; + dst = Math.Sqrt(unit.Protected()).ToUnit(); } } @@ -146,24 +146,24 @@ internal static partial class CollectionsRootOfSquareExtensions where R : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new R[len]; - CollectionsMarshal.AsSpan(units).SqrtCore(len, resultArray.AsSpan()); - return resultArray.WrapAsList(); + var result = new R[count]; + CollectionsMarshal.AsSpan(units).SqrtCore(count, result.AsSpan()); + return result.WrapAsList(); } internal static List Sqrt(this List units) where T : struct, IMensuraUnit, IEquatable where R : struct, IMensuraUnit, IEquatable { if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; + int count = units.Count; + if (count == 0) return []; - var resultArray = new R?[len]; - CollectionsMarshal.AsSpan(units).SqrtCore(len, resultArray.AsSpan()); - return resultArray.WrapAsList(); + var result = new R?[count]; + CollectionsMarshal.AsSpan(units).SqrtCore(count, result.AsSpan()); + return result.WrapAsList(); } // === IReadOnlyCollection === @@ -206,8 +206,7 @@ internal static partial class CollectionsRootOfSquareExtensions foreach (T? item in units) { if ((uint)i >= (uint)count) break; - Unsafe.Add(ref dstRef, i++) = item.HasValue - ? Math.Sqrt(item.Value.ToDouble()).ToUnit() : null; + Unsafe.Add(ref dstRef, i++) = Math.Sqrt(item.Protected()).ToUnit(); } } @@ -224,8 +223,7 @@ internal static partial class CollectionsRootOfSquareExtensions where R : struct, IMensuraUnit, IEquatable { foreach (var item in units) - yield return item.HasValue - ? Math.Sqrt(item.Value.ToDouble()).ToUnit() : null; + yield return Math.Sqrt(item.Protected()).ToUnit(); } // === IEnumerable API === @@ -239,7 +237,7 @@ internal static partial class CollectionsRootOfSquareExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Sqrt(arr); + arr.SqrtCore(arr.Length, arr); return arr.ReCast(); } else return SqrtIterator(units); @@ -254,7 +252,7 @@ internal static partial class CollectionsRootOfSquareExtensions if (units is IReadOnlyCollection roc) { var arr = roc.ToArray(); - arr.Sqrt(arr); + arr.SqrtCore(arr.Length, arr); return arr.ReCast(); } else return SqrtNullableIterator(units); diff --git a/QWERTYkez.Mensura/Extensions/DoubleExtensions.cs b/QWERTYkez.Mensura/Extensions/DoubleExtensions.cs index f2babe9..4a56392 100644 --- a/QWERTYkez.Mensura/Extensions/DoubleExtensions.cs +++ b/QWERTYkez.Mensura/Extensions/DoubleExtensions.cs @@ -16,18 +16,18 @@ internal static partial class DoubleExtensions internal static double ToDouble(this float number) => number; internal static double ToDouble(this decimal number) => (double)number; - internal static double ToDouble(this byte? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this sbyte? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this short? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this ushort? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this int? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this uint? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this nint? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this nuint? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this long? number) => number.HasValue ? number.Value : 0d; - internal static double ToDouble(this ulong? number) => number.HasValue ? number.Value : 0d; + internal static double ToDouble(this byte? number) => number ?? 0d; + internal static double ToDouble(this sbyte? number) => number ?? 0d; + internal static double ToDouble(this short? number) => number ?? 0d; + internal static double ToDouble(this ushort? number) => number ?? 0d; + internal static double ToDouble(this int? number) => number ?? 0d; + internal static double ToDouble(this uint? number) => number ?? 0d; + internal static double ToDouble(this nint? number) => number ?? 0d; + internal static double ToDouble(this nuint? number) => number ?? 0d; + internal static double ToDouble(this long? number) => number ?? 0d; + internal static double ToDouble(this ulong? number) => number ?? 0d; internal static double ToDouble(this Half? number) => number.HasValue ? (double)number.Value : 0d; - internal static double ToDouble(this float? number) => number.HasValue ? number.Value : 0d; + internal static double ToDouble(this float? number) => number ?? 0d; internal static double ToDouble(this decimal? number) => number.HasValue ? (double)number.Value : 0d; #if NET7_0_OR_GREATER @@ -1432,12 +1432,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1451,12 +1451,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1470,12 +1470,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1489,12 +1489,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1508,12 +1508,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1527,12 +1527,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1546,12 +1546,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1565,12 +1565,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1584,12 +1584,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1603,12 +1603,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1622,12 +1622,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)(double)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)(double)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)(double)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)(double)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)(double)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1641,12 +1641,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)(double)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)(double)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)(double)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)(double)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)(double)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1660,12 +1660,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)(double)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)(double)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)(double)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)(double)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)(double)u.Value : null; } } #if NET7_0_OR_GREATER @@ -1680,12 +1680,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)(double)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)(double)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)(double)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)(double)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)(double)u.Value : null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1699,12 +1699,12 @@ internal static partial class DoubleExtensions { var u0 = Unsafe.Add(ref srcRef, i); var u1 = Unsafe.Add(ref srcRef, i + 1); var u2 = Unsafe.Add(ref srcRef, i + 2); var u3 = Unsafe.Add(ref srcRef, i + 3); - Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double)u0.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double)u1.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double)u2.GetValueOrDefault() : null; - Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double)u3.GetValueOrDefault() : null; + Unsafe.Add(ref dstRef, i) = u0.HasValue ? (double?)(double)u0.Value : null; + Unsafe.Add(ref dstRef, i + 1) = u1.HasValue ? (double?)(double)u1.Value : null; + Unsafe.Add(ref dstRef, i + 2) = u2.HasValue ? (double?)(double)u2.Value : null; + Unsafe.Add(ref dstRef, i + 3) = u3.HasValue ? (double?)(double)u3.Value : null; } - for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double)u.GetValueOrDefault() : null; } + for (; i < len; i++) { var u = Unsafe.Add(ref srcRef, i); Unsafe.Add(ref dstRef, i) = u.HasValue ? (double?)(double)u.Value : null; } } #endif diff --git a/QWERTYkez.Mensura/Units/XXXXXXXX.Gen.cs b/QWERTYkez.Mensura/Units/XXXXXXXX.Gen.cs index 8b1c534..c2587d4 100644 --- a/QWERTYkez.Mensura/Units/XXXXXXXX.Gen.cs +++ b/QWERTYkez.Mensura/Units/XXXXXXXX.Gen.cs @@ -926,14 +926,6 @@ public readonly partial record struct XXXXXXXX : IMensuraUnit, IEquata public static class XXXXXXXXExtensions { - internal static double Protected(this XXXXXXXX? unit) => unit is null ? 0d : unit.Value._Value; - internal static XXXXXXXX ProtectedU(this XXXXXXXX? unit) => unit is null ? XXXXXXXX.Zero : unit.Value; - - - - - - // === ReadOnlySpan [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ReadOnlySpan units, double divisor, Span destination) => units.Div(divisor, destination);