++
This commit is contained in:
@@ -247,7 +247,7 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
string propName = baseProp.Name;
|
||||
|
||||
// Создаём массив из двух тестовых значений
|
||||
sb.AppendLine($" private {typeName}[] GetTestArray() => new[] {{ {typeName}.{propName}, {typeName}.{propName} }};");
|
||||
sb.AppendLine($" private {typeName}[] {typeName}_GetTestArray() => {typeName}.{propName}.Mul(new double[] {{ 5d, 3d }});");
|
||||
sb.AppendLine();
|
||||
|
||||
// ========== Multiply ==========
|
||||
@@ -255,57 +255,57 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ScalarByArray_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Multiply(arr);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var arr = {typeName}_GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Mul(arr);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal(scalar * 5d, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal(scalar * 3d, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// array * scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ArrayByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Multiply(scalar);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var arr = {typeName}_GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Mul(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal(scalar * 5d, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal(scalar * 3d, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar * List
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ScalarByList_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Multiply(list);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var list = {typeName}_GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Mul(list);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal(scalar * 5d, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal(scalar * 3d, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// List * scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ListByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Multiply(scalar);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var list = {typeName}_GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Mul(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal(scalar * 5d, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal(scalar * 3d, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar * IEnumerable
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ScalarByEnumerable_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Multiply(enumerable);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var enumerable = {typeName}_GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Mul(enumerable);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
@@ -315,9 +315,9 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_EnumerableByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Multiply(scalar);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var enumerable = {typeName}_GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Mul(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
@@ -329,9 +329,9 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ScalarByArray_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Divide(arr);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var arr = {typeName}_GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Div(arr);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[1], Tolerance);");
|
||||
@@ -341,9 +341,9 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ArrayByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Divide(scalar);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var arr = {typeName}_GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Div(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[1], Tolerance);");
|
||||
@@ -353,9 +353,9 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ScalarByList_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Divide(list);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var list = {typeName}_GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Div(list);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[1], Tolerance);");
|
||||
@@ -365,9 +365,9 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ListByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Divide(scalar);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var list = {typeName}_GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Div(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[1], Tolerance);");
|
||||
@@ -377,9 +377,9 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ScalarByEnumerable_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Divide(enumerable);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var enumerable = {typeName}_GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Div(enumerable);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
@@ -389,9 +389,9 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_EnumerableByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Divide(scalar);");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var enumerable = {typeName}_GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Div(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
@@ -403,8 +403,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ScalarByArray_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var arr = {typeName}_GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Plus(arr);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[0], Tolerance);");
|
||||
@@ -415,8 +415,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ArrayByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var arr = {typeName}_GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Plus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[0], Tolerance);");
|
||||
@@ -427,8 +427,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ScalarByList_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var list = {typeName}_GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Plus(list);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[0], Tolerance);");
|
||||
@@ -439,8 +439,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ListByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var list = {typeName}_GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Plus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[0], Tolerance);");
|
||||
@@ -451,8 +451,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ScalarByEnumerable_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var enumerable = {typeName}_GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Plus(enumerable);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
@@ -463,8 +463,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_EnumerableByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var enumerable = {typeName}_GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Plus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
@@ -477,8 +477,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ScalarByArray_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var arr = {typeName}_GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Minus(arr);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[0], Tolerance);");
|
||||
@@ -489,8 +489,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ArrayByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var arr = {typeName}_GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Minus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[0], Tolerance);");
|
||||
@@ -501,8 +501,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ScalarByList_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var list = {typeName}_GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Minus(list);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[0], Tolerance);");
|
||||
@@ -513,8 +513,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ListByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var list = {typeName}_GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Minus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[0], Tolerance);");
|
||||
@@ -525,8 +525,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ScalarByEnumerable_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var enumerable = {typeName}_GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Minus(enumerable);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
@@ -537,8 +537,8 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_EnumerableByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var scalar = 9d;");
|
||||
sb.AppendLine($" var enumerable = {typeName}_GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Minus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
|
||||
@@ -85,4 +85,32 @@ internal static partial class CastExtensions
|
||||
{
|
||||
return Unsafe.As<T?[], R?[]>(ref array);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static double[] ReCast<T>(this T[] array)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
return Unsafe.As<T[], double[]>(ref array);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static double?[] ReCast<T>(this T?[] array)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
return Unsafe.As<T?[], double?[]>(ref array);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static R[] ReCast<R>(this double[] array)
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
return Unsafe.As<double[], R[]>(ref array);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static R?[] ReCast<R>(this double?[] array)
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
return Unsafe.As<double?[], R?[]>(ref array);
|
||||
}
|
||||
}
|
||||
@@ -921,4 +921,705 @@ internal static partial class CollectionsDivideExtensions
|
||||
}
|
||||
return DivideNullableIterator(dividend, units);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// === DivideCore === SIMD
|
||||
internal static void DivCore<T, R>(this ReadOnlySpan<double> dividends, T unit, int len, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
Span<double> dstDouble = MemoryMarshal.Cast<R, double>(destination);
|
||||
|
||||
// Вместо деления в цикле, умножаем на обратное число (invDivisor)
|
||||
double invDivisor = 1.0 / unit.ToDouble();
|
||||
var vectorizedInvDivisor = new Vector<double>(invDivisor);
|
||||
|
||||
int vectorSize = Vector<double>.Count;
|
||||
int i = 0;
|
||||
|
||||
ref double srcRef = ref MemoryMarshal.GetReference(dividends);
|
||||
ref double dstRef = ref MemoryMarshal.GetReference(dstDouble);
|
||||
|
||||
int simdEnd = len & ~(vectorSize - 1);
|
||||
|
||||
for (; i < simdEnd; i += vectorSize)
|
||||
{
|
||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||
|
||||
// Загрузка, быстрое умножение вместо деления, и сохранение
|
||||
var vector = Unsafe.As<double, Vector<double>>(ref currentSrc);
|
||||
var multiplied = vector * vectorizedInvDivisor;
|
||||
|
||||
Unsafe.As<double, Vector<double>>(ref currentDst) = multiplied;
|
||||
}
|
||||
|
||||
// Хвост
|
||||
for (; i < len; i++)
|
||||
{
|
||||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * invDivisor;
|
||||
}
|
||||
}
|
||||
internal static void DivCore<T, R>(this ReadOnlySpan<double?> dividends, T unit, int len, Span<R?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
// Получаем прямые неуправляемые ref-ссылки на начало буферов за 0 тактов
|
||||
ref var srcRef = ref MemoryMarshal.GetReference(dividends);
|
||||
ref var dstRef = ref MemoryMarshal.GetReference(destination);
|
||||
|
||||
int i = 0;
|
||||
int unrollEnd = len & ~3; // Граница развернутого цикла (кратная 4)
|
||||
double invDivisor = 1.0 / unit.ToDouble();
|
||||
|
||||
// 1. ОСНОВНОЙ ЦИКЛ: Обрабатываем конвейером по 4 элемента за итерацию
|
||||
for (; i < unrollEnd; i += 4)
|
||||
{
|
||||
double? u0 = Unsafe.Add(ref srcRef, i);
|
||||
double? u1 = Unsafe.Add(ref srcRef, i + 1);
|
||||
double? u2 = Unsafe.Add(ref srcRef, i + 2);
|
||||
double? u3 = Unsafe.Add(ref srcRef, i + 3);
|
||||
|
||||
// Получаем ref-ссылки на ячейки назначения (zero-cost адресация)
|
||||
ref var d0 = ref Unsafe.Add(ref dstRef, i);
|
||||
ref var d1 = ref Unsafe.Add(ref dstRef, i + 1);
|
||||
ref var d2 = ref Unsafe.Add(ref dstRef, i + 2);
|
||||
ref var d3 = ref Unsafe.Add(ref dstRef, i + 3);
|
||||
|
||||
// Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага)
|
||||
d0 = u0.HasValue ? (u0.Value * invDivisor).ToUnit<R>() : null;
|
||||
d1 = u1.HasValue ? (u1.Value * invDivisor).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (u2.Value * invDivisor).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (u3.Value * invDivisor).ToUnit<R>() : null;
|
||||
}
|
||||
|
||||
// 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук)
|
||||
for (; i < len; i++)
|
||||
{
|
||||
double? div = Unsafe.Add(ref srcRef, i);
|
||||
ref var dst = ref Unsafe.Add(ref dstRef, i);
|
||||
|
||||
dst = div.HasValue ? (div.Value * invDivisor).ToUnit<R>() : null;
|
||||
}
|
||||
}
|
||||
//SIMD
|
||||
internal static void DivCore<T, R>(this T unit, ReadOnlySpan<double> divisors, int len, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
var dUnit = unit.ToDouble();
|
||||
Span<double> dstDouble = MemoryMarshal.Cast<R, double>(destination);
|
||||
|
||||
var vectorizedDividend = new Vector<double>(dUnit);
|
||||
int vectorSize = Vector<double>.Count;
|
||||
int i = 0;
|
||||
|
||||
ref double srcRef = ref MemoryMarshal.GetReference(divisors);
|
||||
ref double dstRef = ref MemoryMarshal.GetReference(dstDouble);
|
||||
|
||||
int simdEnd = len & ~(vectorSize - 1);
|
||||
|
||||
for (; i < simdEnd; i += vectorSize)
|
||||
{
|
||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||
|
||||
var vector = Unsafe.As<double, Vector<double>>(ref currentSrc);
|
||||
|
||||
// Векторное деление: константа делится на покомпонентные элементы массива
|
||||
var divided = Vector.Divide(vectorizedDividend, vector);
|
||||
|
||||
Unsafe.As<double, Vector<double>>(ref currentDst) = divided;
|
||||
}
|
||||
|
||||
// Хвост
|
||||
for (; i < len; i++)
|
||||
{
|
||||
Unsafe.Add(ref dstRef, i) = dUnit / Unsafe.Add(ref srcRef, i);
|
||||
}
|
||||
}
|
||||
internal static void DivCore<T, R>(this T unit, ReadOnlySpan<double?> divisors, int len, Span<R?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
var dUnit = unit.ToDouble();
|
||||
// Получаем прямые неуправляемые ref-ссылки на начало буферов за 0 тактов
|
||||
ref var srcRef = ref MemoryMarshal.GetReference(divisors);
|
||||
ref var dstRef = ref MemoryMarshal.GetReference(destination);
|
||||
|
||||
int i = 0;
|
||||
int unrollEnd = len & ~3; // Граница развернутого цикла (кратная 4)
|
||||
|
||||
// 1. ОСНОВНОЙ ЦИКЛ: Обрабатываем конвейером по 4 элемента за итерацию
|
||||
for (; i < unrollEnd; i += 4)
|
||||
{
|
||||
double? u0 = Unsafe.Add(ref srcRef, i);
|
||||
double? u1 = Unsafe.Add(ref srcRef, i + 1);
|
||||
double? u2 = Unsafe.Add(ref srcRef, i + 2);
|
||||
double? u3 = Unsafe.Add(ref srcRef, i + 3);
|
||||
|
||||
// Получаем ref-ссылки на ячейки назначения (zero-cost адресация)
|
||||
ref var d0 = ref Unsafe.Add(ref dstRef, i);
|
||||
ref var d1 = ref Unsafe.Add(ref dstRef, i + 1);
|
||||
ref var d2 = ref Unsafe.Add(ref dstRef, i + 2);
|
||||
ref var d3 = ref Unsafe.Add(ref dstRef, i + 3);
|
||||
|
||||
// Пишем строго по месту. Если HasValue == false, в ячейку dX запишется null (сбросятся байты флага)
|
||||
d0 = u0.HasValue ? (dUnit / u0.Value).ToUnit<R>() : null;
|
||||
d1 = u1.HasValue ? (dUnit / u1.Value).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (dUnit / u2.Value).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (dUnit / u3.Value).ToUnit<R>() : null;
|
||||
}
|
||||
|
||||
// 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук)
|
||||
for (; i < len; i++)
|
||||
{
|
||||
double? div = Unsafe.Add(ref srcRef, i);
|
||||
ref var dst = ref Unsafe.Add(ref dstRef, i);
|
||||
|
||||
dst = div.HasValue ? (unit.ToDouble() / div.Value).ToUnit<R>() : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === DivideCore === SIMD
|
||||
internal static void DivCore(this ReadOnlySpan<double> dividends, double unit, int len, Span<double> dstDouble)
|
||||
{
|
||||
// Вместо деления в цикле, умножаем на обратное число (invDivisor)
|
||||
double invDivisor = 1.0 / unit;
|
||||
var vectorizedInvDivisor = new Vector<double>(invDivisor);
|
||||
|
||||
int vectorSize = Vector<double>.Count;
|
||||
int i = 0;
|
||||
|
||||
ref double srcRef = ref MemoryMarshal.GetReference(dividends);
|
||||
ref double dstRef = ref MemoryMarshal.GetReference(dstDouble);
|
||||
|
||||
int simdEnd = len & ~(vectorSize - 1);
|
||||
|
||||
for (; i < simdEnd; i += vectorSize)
|
||||
{
|
||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||
|
||||
// Загрузка, быстрое умножение вместо деления, и сохранение
|
||||
var vector = Unsafe.As<double, Vector<double>>(ref currentSrc);
|
||||
var multiplied = vector * vectorizedInvDivisor;
|
||||
|
||||
Unsafe.As<double, Vector<double>>(ref currentDst) = multiplied;
|
||||
}
|
||||
|
||||
// Хвост
|
||||
for (; i < len; i++)
|
||||
{
|
||||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * invDivisor;
|
||||
}
|
||||
}
|
||||
internal static void DivCore(this ReadOnlySpan<double?> dividends, double unit, int len, Span<double?> destination)
|
||||
{
|
||||
// Получаем прямые неуправляемые ref-ссылки на начало буферов за 0 тактов
|
||||
ref var srcRef = ref MemoryMarshal.GetReference(dividends);
|
||||
ref var dstRef = ref MemoryMarshal.GetReference(destination);
|
||||
|
||||
int i = 0;
|
||||
int unrollEnd = len & ~3; // Граница развернутого цикла (кратная 4)
|
||||
double invDivisor = 1.0 / unit;
|
||||
|
||||
// 1. ОСНОВНОЙ ЦИКЛ: Обрабатываем конвейером по 4 элемента за итерацию
|
||||
for (; i < unrollEnd; i += 4)
|
||||
{
|
||||
double? u0 = Unsafe.Add(ref srcRef, i);
|
||||
double? u1 = Unsafe.Add(ref srcRef, i + 1);
|
||||
double? u2 = Unsafe.Add(ref srcRef, i + 2);
|
||||
double? u3 = Unsafe.Add(ref srcRef, i + 3);
|
||||
|
||||
// Получаем ref-ссылки на ячейки назначения (zero-cost адресация)
|
||||
ref var d0 = ref Unsafe.Add(ref dstRef, i);
|
||||
ref var d1 = ref Unsafe.Add(ref dstRef, i + 1);
|
||||
ref var d2 = ref Unsafe.Add(ref dstRef, i + 2);
|
||||
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;
|
||||
}
|
||||
|
||||
// 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук)
|
||||
for (; i < len; i++)
|
||||
{
|
||||
double? div = Unsafe.Add(ref srcRef, i);
|
||||
ref var dst = ref Unsafe.Add(ref dstRef, i);
|
||||
|
||||
dst = div.HasValue ? div.Value * invDivisor : null;
|
||||
}
|
||||
}
|
||||
//SIMD
|
||||
internal static void DivCore(this double dUnit, ReadOnlySpan<double> divisors, int len, Span<double> dstDouble)
|
||||
{
|
||||
var vectorizedDividend = new Vector<double>(dUnit);
|
||||
int vectorSize = Vector<double>.Count;
|
||||
int i = 0;
|
||||
|
||||
ref double srcRef = ref MemoryMarshal.GetReference(divisors);
|
||||
ref double dstRef = ref MemoryMarshal.GetReference(dstDouble);
|
||||
|
||||
int simdEnd = len & ~(vectorSize - 1);
|
||||
|
||||
for (; i < simdEnd; i += vectorSize)
|
||||
{
|
||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||
|
||||
var vector = Unsafe.As<double, Vector<double>>(ref currentSrc);
|
||||
|
||||
// Векторное деление: константа делится на покомпонентные элементы массива
|
||||
var divided = Vector.Divide(vectorizedDividend, vector);
|
||||
|
||||
Unsafe.As<double, Vector<double>>(ref currentDst) = divided;
|
||||
}
|
||||
|
||||
// Хвост
|
||||
for (; i < len; i++)
|
||||
{
|
||||
Unsafe.Add(ref dstRef, i) = dUnit / Unsafe.Add(ref srcRef, i);
|
||||
}
|
||||
}
|
||||
internal static void DivCore(this double dUnit, ReadOnlySpan<double?> divisors, int len, Span<double?> destination)
|
||||
{
|
||||
// Получаем прямые неуправляемые ref-ссылки на начало буферов за 0 тактов
|
||||
ref var srcRef = ref MemoryMarshal.GetReference(divisors);
|
||||
ref var dstRef = ref MemoryMarshal.GetReference(destination);
|
||||
|
||||
int i = 0;
|
||||
int unrollEnd = len & ~3; // Граница развернутого цикла (кратная 4)
|
||||
|
||||
// 1. ОСНОВНОЙ ЦИКЛ: Обрабатываем конвейером по 4 элемента за итерацию
|
||||
for (; i < unrollEnd; i += 4)
|
||||
{
|
||||
double? u0 = Unsafe.Add(ref srcRef, i);
|
||||
double? u1 = Unsafe.Add(ref srcRef, i + 1);
|
||||
double? u2 = Unsafe.Add(ref srcRef, i + 2);
|
||||
double? u3 = Unsafe.Add(ref srcRef, i + 3);
|
||||
|
||||
// Получаем ref-ссылки на ячейки назначения (zero-cost адресация)
|
||||
ref var d0 = ref Unsafe.Add(ref dstRef, i);
|
||||
ref var d1 = ref Unsafe.Add(ref dstRef, i + 1);
|
||||
ref var d2 = ref Unsafe.Add(ref dstRef, i + 2);
|
||||
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;
|
||||
}
|
||||
|
||||
// 2. ХВОСТ ЦИКЛА: Довычисляем остаток элементов (от 1 до 3 штук)
|
||||
for (; i < len; i++)
|
||||
{
|
||||
double? div = Unsafe.Add(ref srcRef, i);
|
||||
ref var dst = ref Unsafe.Add(ref dstRef, i);
|
||||
|
||||
dst = div.HasValue ? dUnit / div.Value : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// === ReadOnlySpan
|
||||
internal static void Div<T>(this ReadOnlySpan<double> units, T divisor, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units.IsEmpty) return;
|
||||
int len = units.Length;
|
||||
if (len > destination.Length)
|
||||
throw new ArgumentException("Целевой буфер destination меньше исходного source.");
|
||||
|
||||
units.DivCore(divisor, len, destination);
|
||||
}
|
||||
internal static void Div<T>(this ReadOnlySpan<double?> units, T divisor, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units.IsEmpty) return;
|
||||
int len = units.Length;
|
||||
if (len > destination.Length)
|
||||
throw new ArgumentException("Целевой буфер destination меньше исходного source.");
|
||||
|
||||
units.DivCore(divisor, len, destination);
|
||||
}
|
||||
internal static void Div<T>(this T dividend, ReadOnlySpan<double> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units.IsEmpty) return;
|
||||
int len = units.Length;
|
||||
if (len > destination.Length)
|
||||
throw new ArgumentException("Целевой буфер destination меньше исходного source.");
|
||||
|
||||
dividend.DivCore(units, len, destination);
|
||||
}
|
||||
internal static void Div<T>(this T dividend, ReadOnlySpan<double?> units, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units.IsEmpty) return;
|
||||
int len = units.Length;
|
||||
if (len > destination.Length)
|
||||
throw new ArgumentException("Целевой буфер destination меньше исходного source.");
|
||||
|
||||
dividend.DivCore(units, len, destination);
|
||||
}
|
||||
|
||||
// === Array ===
|
||||
internal static T[] Div<T>(this double[] units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
int len = units.Length;
|
||||
if (len == 0) return [];
|
||||
|
||||
var result = new T[len];
|
||||
Div(units, divisor, result);
|
||||
return result;
|
||||
}
|
||||
internal static T?[] Div<T>(this double?[] units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
int len = units.Length;
|
||||
if (len == 0) return [];
|
||||
|
||||
var result = new T?[len];
|
||||
Div(units, divisor, result);
|
||||
return result;
|
||||
}
|
||||
internal static T[] Div<T>(this T dividend, double[] units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
int len = units.Length;
|
||||
if (len == 0) return [];
|
||||
|
||||
var result = new T[len];
|
||||
Div(dividend, units, result);
|
||||
return result;
|
||||
}
|
||||
internal static T?[] Div<T>(this T dividend, double?[] units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
int len = units.Length;
|
||||
if (len == 0) return [];
|
||||
|
||||
var result = new T?[len];
|
||||
Div(dividend, units, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// === List<T> ===
|
||||
internal static List<T> Div<T>(this List<double> units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
int len = units.Count;
|
||||
if (len == 0) return [];
|
||||
|
||||
var resultArray = new T[len];
|
||||
Div(CollectionsMarshal.AsSpan(units), divisor, resultArray);
|
||||
return resultArray.WrapAsList();
|
||||
}
|
||||
internal static List<T?> Div<T>(this List<double?> units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
int count = units.Count;
|
||||
if (count == 0) return [];
|
||||
|
||||
var resultArray = new T?[count];
|
||||
Div(CollectionsMarshal.AsSpan(units), divisor, resultArray);
|
||||
return resultArray.WrapAsList();
|
||||
}
|
||||
internal static List<T> Div<T>(this T dividend, List<double> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
int count = units.Count;
|
||||
if (count == 0) return [];
|
||||
|
||||
var resultArray = new T[count];
|
||||
Div(dividend, CollectionsMarshal.AsSpan(units), resultArray);
|
||||
return resultArray.WrapAsList();
|
||||
}
|
||||
internal static List<T?> Div<T>(this T dividend, List<double?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
int count = units.Count;
|
||||
if (count == 0) return [];
|
||||
|
||||
var resultArray = new T?[count];
|
||||
Div(dividend, CollectionsMarshal.AsSpan(units), resultArray);
|
||||
return resultArray.WrapAsList();
|
||||
}
|
||||
|
||||
// === ICollection<T> ===
|
||||
internal static void Div<T>(this ICollection<double> units, T divisor, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return;
|
||||
int count = units.Count;
|
||||
if (count == 0) return;
|
||||
if (destination.Length < count)
|
||||
throw new ArgumentException("Destination too short");
|
||||
|
||||
if (units is double[] array) { array.Div(divisor, destination); return; }
|
||||
if (units is List<double> list) { CollectionsMarshal.AsSpan(list).Div(divisor, destination); return; }
|
||||
|
||||
int i = 0;
|
||||
double invDivisor = 1.0 / divisor.ToDouble();
|
||||
foreach (var item in units)
|
||||
destination[i++] = (item * invDivisor).ToUnit<T>();
|
||||
}
|
||||
internal static void Div<T>(this ICollection<double?> units, T divisor, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return;
|
||||
int count = units.Count;
|
||||
if (count == 0) return;
|
||||
if (destination.Length < count)
|
||||
throw new ArgumentException("Destination too short");
|
||||
|
||||
if (units is double?[] array) { array.Div(divisor, destination); return; }
|
||||
if (units is List<double?> list) { CollectionsMarshal.AsSpan(list).Div(divisor, destination); return; }
|
||||
|
||||
int i = 0;
|
||||
double invDivisor = 1.0 / divisor.ToDouble();
|
||||
foreach (var item in units)
|
||||
destination[i++] = item.HasValue
|
||||
? (item.Value * invDivisor).ToUnit<T>() : null;
|
||||
}
|
||||
internal static void Div<T>(this T dividend, ICollection<double> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return;
|
||||
int count = units.Count;
|
||||
if (count == 0) return;
|
||||
if (destination.Length < count)
|
||||
throw new ArgumentException("Destination too short");
|
||||
|
||||
if (units is double[] array) { dividend.Div(array, destination); return; }
|
||||
if (units is List<double> list) { dividend.Div(CollectionsMarshal.AsSpan(list), destination); return; }
|
||||
|
||||
int i = 0;
|
||||
foreach (var item in units)
|
||||
destination[i++] = (dividend.ToDouble() / item).ToUnit<T>();
|
||||
}
|
||||
internal static void Div<T>(this T dividend, ICollection<double?> units, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return;
|
||||
int count = units.Count;
|
||||
if (count == 0) return;
|
||||
if (destination.Length < count)
|
||||
throw new ArgumentException("Destination too short");
|
||||
|
||||
if (units is double?[] array) { dividend.Div(array, destination); return; }
|
||||
if (units is List<double?> list) { dividend.Div(CollectionsMarshal.AsSpan(list), destination); return; }
|
||||
|
||||
int i = 0;
|
||||
foreach (var item in units)
|
||||
destination[i++] = item.HasValue
|
||||
? (dividend.ToDouble() / item.Value).ToUnit<T>() : null;
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<T> ===
|
||||
internal static void Div<T>(this IReadOnlyCollection<double> units, T divisor, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return;
|
||||
int count = units.Count;
|
||||
if (count == 0) return;
|
||||
if (destination.Length < count)
|
||||
throw new ArgumentException("Destination too short");
|
||||
|
||||
if (units is double[] array) { array.Div(divisor, destination); return; }
|
||||
if (units is List<double> list) { CollectionsMarshal.AsSpan(list).Div(divisor, destination); return; }
|
||||
|
||||
int i = 0;
|
||||
double invDivisor = 1.0 / divisor.ToDouble();
|
||||
foreach (var item in units)
|
||||
destination[i++] = (item * invDivisor).ToUnit<T>();
|
||||
}
|
||||
internal static void Div<T>(this IReadOnlyCollection<double?> units, T divisor, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return;
|
||||
int count = units.Count;
|
||||
if (count == 0) return;
|
||||
if (destination.Length < count)
|
||||
throw new ArgumentException("Destination too short");
|
||||
|
||||
if (units is double?[] array) { array.Div(divisor, destination); return; }
|
||||
if (units is List<double?> list) { CollectionsMarshal.AsSpan(list).Div(divisor, destination); return; }
|
||||
|
||||
int i = 0;
|
||||
double invDivisor = 1.0 / divisor.ToDouble();
|
||||
foreach (var item in units)
|
||||
destination[i++] = item.HasValue
|
||||
? (item.Value * invDivisor).ToUnit<T>() : null;
|
||||
}
|
||||
internal static void Div<T>(this T dividend, IReadOnlyCollection<double> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return;
|
||||
int count = units.Count;
|
||||
if (count == 0) return;
|
||||
if (destination.Length < count)
|
||||
throw new ArgumentException("Destination too short");
|
||||
|
||||
if (units is double[] array) { dividend.Div(array, destination); return; }
|
||||
if (units is List<double> list) { dividend.Div(CollectionsMarshal.AsSpan(list), destination); return; }
|
||||
|
||||
int i = 0;
|
||||
foreach (var item in units)
|
||||
destination[i++] = (dividend.ToDouble() / item).ToUnit<T>();
|
||||
}
|
||||
internal static void Div<T>(this T dividend, IReadOnlyCollection<double?> units, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return;
|
||||
int count = units.Count;
|
||||
if (count == 0) return;
|
||||
if (destination.Length < count)
|
||||
throw new ArgumentException("Destination too short");
|
||||
|
||||
if (units is double?[] array) { dividend.Div(array, destination); return; }
|
||||
if (units is List<double?> list) { dividend.Div(CollectionsMarshal.AsSpan(list), destination); return; }
|
||||
|
||||
int i = 0;
|
||||
foreach (var item in units)
|
||||
destination[i++] = item.HasValue
|
||||
? (dividend.ToDouble() / item.Value).ToUnit<T>() : null;
|
||||
}
|
||||
|
||||
// === IEnumerable<T> + yeild ===
|
||||
static IEnumerable<T> DivideIterator<T>(IEnumerable<double> units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
double invDivisor = 1.0 / divisor.ToDouble();
|
||||
foreach (var item in units)
|
||||
yield return (item * invDivisor).ToUnit<T>();
|
||||
}
|
||||
static IEnumerable<T?> DivideNullableIterator<T>(IEnumerable<double?> units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
double invDivisor = 1.0 / divisor.ToDouble();
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value * invDivisor).ToUnit<T>() : null;
|
||||
}
|
||||
static IEnumerable<T> DivideIterator<T>(T dividend, IEnumerable<double> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return (dividend.ToDouble() / item).ToUnit<T>();
|
||||
}
|
||||
static IEnumerable<T?> DivideNullableIterator<T>(T dividend, IEnumerable<double?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? (dividend.ToDouble() / item.Value).ToUnit<T>() : null;
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
internal static IEnumerable<T> Div<T>(this IEnumerable<double> units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
if (units is double[] array) return array.Div(divisor);
|
||||
if (units is List<double> list) return list.Div(divisor);
|
||||
if (units is ICollection<double> col)
|
||||
{
|
||||
var arr = col.ToArray();
|
||||
arr.DivCore(divisor.ToDouble(), arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
if (units is IReadOnlyCollection<double> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.DivCore(divisor.ToDouble(), arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return DivideIterator(units, divisor);
|
||||
}
|
||||
internal static IEnumerable<T?> Div<T>(this IEnumerable<double?> units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
if (units is double?[] array) return array.Div(divisor);
|
||||
if (units is List<double?> list) return list.Div(divisor);
|
||||
if (units is ICollection<double?> col)
|
||||
{
|
||||
var arr = col.ToArray();
|
||||
arr.DivCore(divisor.ToDouble(), arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
if (units is IReadOnlyCollection<double?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.DivCore(divisor.ToDouble(), arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return DivideNullableIterator(units, divisor);
|
||||
}
|
||||
internal static IEnumerable<T> Div<T>(this T dividend, IEnumerable<double> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
if (units is double[] array) return dividend.Div(array);
|
||||
if (units is List<double> list) return dividend.Div(list);
|
||||
if (units is ICollection<double> col)
|
||||
{
|
||||
var arr = col.ToArray();
|
||||
dividend.ToDouble().DivCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
if (units is IReadOnlyCollection<double> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
dividend.ToDouble().DivCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return DivideIterator(dividend, units);
|
||||
}
|
||||
internal static IEnumerable<T?> Div<T>(this T dividend, IEnumerable<double?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
if (units is double?[] array) return dividend.Div(array);
|
||||
if (units is List<double?> list) return dividend.Div(list);
|
||||
if (units is ICollection<double?> col)
|
||||
{
|
||||
var arr = col.ToArray();
|
||||
dividend.ToDouble().DivCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
if (units is IReadOnlyCollection<double?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
dividend.ToDouble().DivCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return DivideNullableIterator(dividend, units);
|
||||
}
|
||||
}
|
||||
1559
QWERTYkez.Mensura/Extensions/DoubleExtensions.cs
Normal file
1559
QWERTYkez.Mensura/Extensions/DoubleExtensions.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,38 +0,0 @@
|
||||
namespace QWERTYkez.Mensura.Extensions;
|
||||
|
||||
internal static partial class ToDoubleExtensions
|
||||
{
|
||||
internal static double ToDouble(this sbyte number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this short number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this int number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this long number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this byte number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this ushort number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this uint number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this ulong number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this nint number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this nuint number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this float number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this decimal number) => Convert.ToDouble(number);
|
||||
|
||||
internal static double ToDouble(this sbyte? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this short? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this int? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this long? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this byte? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this ushort? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this uint? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this ulong? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this nint? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this nuint? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this float? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this decimal? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
internal static double ToDouble(this Int128 number) => Convert.ToDouble(number);
|
||||
internal static double ToDouble(this UInt128 number) => Convert.ToDouble(number);
|
||||
|
||||
internal static double ToDouble(this Int128? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
internal static double ToDouble(this UInt128? number) => number is null ? 0d : Convert.ToDouble(number);
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user