Merge branch 'master' of https://lancool.qwertykez.fun/QWERTYkez/QWERTYkez.Mensura
All checks were successful
Publish NuGet packages / publish (push) Successful in 1m1s
All checks were successful
Publish NuGet packages / publish (push) Successful in 1m1s
This commit is contained in:
@@ -5,13 +5,19 @@ namespace QWERTYkez.Mensura.Extensions;
|
||||
|
||||
internal static partial class CastExtensions
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static double ToDouble<T>(this T unit) where T : struct, IMensuraUnit, IEquatable<T>
|
||||
=> Unsafe.As<T, double>(ref unit);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double ToDouble<T>(this T unit)
|
||||
where T : struct, IMensuraUnit, IEquatable<T> => Unsafe.As<T, double>(ref unit);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static double Protected<T>(this T? unit)
|
||||
where T : struct, IMensuraUnit, IEquatable<T> => unit.GetValueOrDefault().ToDouble();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static T ProtectedU<T>(this T? unit)
|
||||
where T : struct, IMensuraUnit, IEquatable<T> => unit ?? default;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static T ToUnit<T>(this double val)
|
||||
where T : struct, IMensuraUnit, IEquatable<T> => Unsafe.As<double, T>(ref val);
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static List<R> WrapAsList<T, R>(this T[] array)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
internal static partial class CollectionsDivideExtensions
|
||||
{
|
||||
// === DivideCore === SIMD
|
||||
internal static void DivideCore<T, R>(this ReadOnlySpan<T> units, double divisor, int len, Span<R> destination)
|
||||
// === DivCore === SIMD
|
||||
internal static void DivCore<T, R>(this ReadOnlySpan<T> units, double divisor, int len, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -40,7 +40,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * invDivisor;
|
||||
}
|
||||
}
|
||||
internal static void DivideCore<T, R>(this ReadOnlySpan<T?> units, double divisor, int len, Span<R?> destination)
|
||||
internal static void DivCore<T, R>(this ReadOnlySpan<T?> units, double divisor, int len, Span<R?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -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<R>() : null;
|
||||
d1 = u1.HasValue ? (u1.Value.ToDouble() * invDivisor).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (u2.Value.ToDouble() * invDivisor).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (u3.Value.ToDouble() * invDivisor).ToUnit<R>() : null;
|
||||
d0 = (u0.Protected() * invDivisor).ToUnit<R>();
|
||||
d1 = (u1.Protected() * invDivisor).ToUnit<R>();
|
||||
d2 = (u2.Protected() * invDivisor).ToUnit<R>();
|
||||
d3 = (u3.Protected() * invDivisor).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = (unit.Protected() * invDivisor).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
//SIMD
|
||||
internal static void DivideCore<T, R>(this double dividend, ReadOnlySpan<T> units, int len, Span<R> destination)
|
||||
internal static void DivCore<T, R>(this double dividend, ReadOnlySpan<T> units, int len, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -118,7 +117,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
Unsafe.Add(ref dstRef, i) = dividend / Unsafe.Add(ref srcRef, i);
|
||||
}
|
||||
}
|
||||
internal static void DivideCore<T, R>(this double dividend, ReadOnlySpan<T?> units, int len, Span<R?> destination)
|
||||
internal static void DivCore<T, R>(this double dividend, ReadOnlySpan<T?> units, int len, Span<R?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -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<R>() : null;
|
||||
d1 = u1.HasValue ? (dividend / u1.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (dividend / u2.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (dividend / u3.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d0 = (dividend / u0.Protected()).ToUnit<R>();
|
||||
d1 = (dividend / u1.Protected()).ToUnit<R>();
|
||||
d2 = (dividend / u2.Protected()).ToUnit<R>();
|
||||
d3 = (dividend / u3.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = (dividend / unit.Protected()).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T, R>(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<T, R>(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<T, R>(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<R, R>();
|
||||
var result = new R[count];
|
||||
DivCore(CollectionsMarshal.AsSpan(units), divisor, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Div<T, R>(this List<T?> units, double divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
DivCore(CollectionsMarshal.AsSpan(units), divisor, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R> Div<T, R>(this double dividend, List<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R[count];
|
||||
DivCore(dividend, CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Div<T, R>(this double dividend, List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
DivCore(dividend, CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<T> ===
|
||||
@@ -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<T> list) { CollectionsMarshal.AsSpan(list).DivideCore(divisor, count, destination); return; }
|
||||
if (units is T[] array) { array.DivCore(divisor, count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { CollectionsMarshal.AsSpan(list).DivideCore(divisor, count, destination); return; }
|
||||
if (units is T?[] array) { array.DivCore(divisor, count, destination); return; }
|
||||
if (units is List<T?> 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<R>() : null;
|
||||
destination[i++] = (item.Protected() * invDivisor).ToUnit<R>();
|
||||
}
|
||||
internal static void Div<T, R>(this double dividend, IReadOnlyCollection<T> units, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T> list) { dividend.DivideCore(CollectionsMarshal.AsSpan(list), count, destination); return; }
|
||||
if (units is T[] array) { dividend.DivCore(array, count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { dividend.DivideCore(CollectionsMarshal.AsSpan(list), count, destination); return; }
|
||||
if (units is T?[] array) { dividend.DivCore(array, count, destination); return; }
|
||||
if (units is List<T?> 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<R>() : null;
|
||||
destination[i++] = (dividend / item.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> + 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<R>() : null;
|
||||
yield return (item.Protected() * invDivisor).ToUnit<R>();
|
||||
}
|
||||
static IEnumerable<R> DivideIterator<T, R>(double dividend, IEnumerable<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -368,8 +364,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (dividend / item.Value.ToDouble()).ToUnit<R>() : null;
|
||||
yield return (dividend / item.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -383,7 +378,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Div(divisor, arr);
|
||||
arr.DivCore(divisor, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return DivideIterator<T, R>(units, divisor);
|
||||
@@ -398,7 +393,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Div(divisor, arr);
|
||||
arr.DivCore(divisor, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return DivideNullableIterator<T, R>(units, divisor);
|
||||
@@ -413,7 +408,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
dividend.Div(arr, arr);
|
||||
dividend.DivCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return DivideIterator<T, R>(dividend, units);
|
||||
@@ -428,7 +423,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
dividend.Div(arr, arr);
|
||||
dividend.DivCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return DivideNullableIterator<T, R>(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<T>(this ReadOnlySpan<T?> units, double divisor, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>(this double dividend, ReadOnlySpan<T> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>(this double dividend, ReadOnlySpan<T?> units, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>(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<T>(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<T>(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<T>
|
||||
{
|
||||
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<T, T>();
|
||||
var result = new T[count];
|
||||
CollectionsMarshal.AsSpan(units).DivCore(divisor, count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Div<T>(this List<T?> units, double divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
CollectionsMarshal.AsSpan(units).DivCore(divisor, count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T> Div<T>(this double dividend, List<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T[count];
|
||||
dividend.DivCore(CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Div<T>(this double dividend, List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
dividend.DivCore(CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<T> ===
|
||||
@@ -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<T>() : null;
|
||||
destination[i++] = (item.Protected() * invDivisor).ToUnit<T>();
|
||||
}
|
||||
internal static void Div<T>(this double dividend, IReadOnlyCollection<T> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>() : null;
|
||||
destination[i++] = (dividend / item.Protected()).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> + 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<T>() : null;
|
||||
yield return (item.Protected() * invDivisor).ToUnit<T>();
|
||||
}
|
||||
static IEnumerable<T> DivideIterator<T>(double dividend, IEnumerable<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -668,8 +660,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (dividend / item.Value.ToDouble()).ToUnit<T>() : null;
|
||||
yield return (dividend / item.Protected()).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -682,7 +673,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
if (units is IReadOnlyCollection<T> 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<T?> 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<T> 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<T?> 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<R>(this ReadOnlySpan<double> dividends, double unit, int len, Span<R> destination)
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -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<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;
|
||||
d0 = ((u0 ?? 0d) * invDivisor).ToUnit<R>();
|
||||
d1 = ((u1 ?? 0d) * invDivisor).ToUnit<R>();
|
||||
d2 = ((u2 ?? 0d) * invDivisor).ToUnit<R>();
|
||||
d3 = ((u3 ?? 0d) * invDivisor).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = ((div ?? 0d) * invDivisor).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
//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<R>() : null;
|
||||
d1 = u1.HasValue ? (unit / u1.Value).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (unit / u2.Value).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (unit / u3.Value).ToUnit<R>() : null;
|
||||
d0 = (unit / (u0 ?? 0d)).ToUnit<R>();
|
||||
d1 = (unit / (u1 ?? 0d)).ToUnit<R>();
|
||||
d2 = (unit / (u2 ?? 0d)).ToUnit<R>();
|
||||
d3 = (unit / (u3 ?? 0d)).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = (unit / (div ?? 0d)).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === DivideCore === SIMD
|
||||
// === DivCore === SIMD
|
||||
internal static void DivCore(this ReadOnlySpan<double> dividends, double unit, int len, Span<double> 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<T>(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<T>(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<T>(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<T>
|
||||
{
|
||||
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<T, T>();
|
||||
var result = new T[count];
|
||||
CollectionsMarshal.AsSpan(units).DivCore(divisor.ToDouble(), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Div<T>(this List<double?> units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
CollectionsMarshal.AsSpan(units).DivCore(divisor.ToDouble(), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T> Div<T>(this T dividend, List<double> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T[count];
|
||||
dividend.ToDouble().DivCore(CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Div<T>(this T dividend, List<double?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
dividend.ToDouble().DivCore(CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<T> ===
|
||||
@@ -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<T>() : null;
|
||||
destination[i++] = ((item ?? 0d) * invDivisor).ToUnit<T>();
|
||||
}
|
||||
internal static void Div<T>(this T dividend, IReadOnlyCollection<double> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -1238,9 +1225,9 @@ internal static partial class CollectionsDivideExtensions
|
||||
if (units is List<double?> 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<T>() : null;
|
||||
destination[i++] = (divD / (item ?? 0d)).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> + 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<T>() : null;
|
||||
yield return ((item ?? 0d) * invDivisor).ToUnit<T>();
|
||||
}
|
||||
static IEnumerable<T> DivideIterator<T>(double dividend, IEnumerable<double> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -1269,8 +1255,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? (dividend / item.Value).ToUnit<T>() : null;
|
||||
yield return (dividend / (item ?? 0d)).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -1339,8 +1324,8 @@ internal static partial class CollectionsDivideExtensions
|
||||
|
||||
|
||||
|
||||
// === DivideCore === SIMD
|
||||
internal static void DivideCore<T>(this ReadOnlySpan<T> units, double divisor, int len, Span<double> dstDouble)
|
||||
// === DivCore === SIMD
|
||||
internal static void DivCore<T>(this ReadOnlySpan<T> units, double divisor, int len, Span<double> dstDouble)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<T, double>(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<T>(this ReadOnlySpan<T?> units, double divisor, int len, Span<double?> destination)
|
||||
internal static void DivCore<T>(this ReadOnlySpan<T?> units, double divisor, int len, Span<double?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
// Получаем прямые неуправляемые 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<T>(this double dividend, ReadOnlySpan<T> units, int len, Span<double> dstDouble)
|
||||
internal static void DivCore<T>(this double dividend, ReadOnlySpan<T> units, int len, Span<double> dstDouble)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<T, double>(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<T>(this double dividend, ReadOnlySpan<T?> units, int len, Span<double?> destination)
|
||||
internal static void DivCore<T>(this double dividend, ReadOnlySpan<T?> units, int len, Span<double?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
// Получаем прямые неуправляемые 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<T>(this ReadOnlySpan<T?> units, T divisor, Span<double?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>(this T dividend, ReadOnlySpan<T> units, Span<double> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>(this T dividend, ReadOnlySpan<T?> units, Span<double?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>(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<T>(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<T>(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<double?> Div<T>(this List<T?> units, T divisor)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<double> Div<T>(this T dividend, List<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<double?> Div<T>(this T dividend, List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T> ===
|
||||
@@ -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<T>(this T dividend, IReadOnlyCollection<T> units, Span<double> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T> + 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<double> DivideIterator<T>(T dividend, IEnumerable<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T> ===
|
||||
@@ -1739,7 +1724,7 @@ internal static partial class CollectionsDivideExtensions
|
||||
if (units is IReadOnlyCollection<T> 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<T?> 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<T> 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<T?> 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);
|
||||
|
||||
@@ -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<R>() : null;
|
||||
d1 = u1.HasValue ? (u1.Value.ToDouble() - subtrahend).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (u2.Value.ToDouble() - subtrahend).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (u3.Value.ToDouble() - subtrahend).ToUnit<R>() : null;
|
||||
d0 = (u0.Protected() - subtrahend).ToUnit<R>();
|
||||
d1 = (u1.Protected() - subtrahend).ToUnit<R>();
|
||||
d2 = (u2.Protected() - subtrahend).ToUnit<R>();
|
||||
d3 = (u3.Protected() - subtrahend).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = (unit.Protected() - subtrahend).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
//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<R>() : null;
|
||||
d1 = u1.HasValue ? (minuend - u1.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (minuend - u2.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (minuend - u3.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d0 = (minuend - u0.Protected()).ToUnit<R>();
|
||||
d1 = (minuend - u1.Protected()).ToUnit<R>();
|
||||
d2 = (minuend - u2.Protected()).ToUnit<R>();
|
||||
d3 = (minuend - u3.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = (minuend - unit.Protected()).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<R, R>();
|
||||
var result = new R[count];
|
||||
MinusCore(CollectionsMarshal.AsSpan(units), subtrahend, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Minus<T, R>(this List<T?> units, double subtrahend)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
MinusCore(CollectionsMarshal.AsSpan(units), subtrahend, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R> Minus<T, R>(this double minuend, List<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R[count];
|
||||
MinusCore(minuend, CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Minus<T, R>(this double minuend, List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
MinusCore(minuend, CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<T> ===
|
||||
@@ -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<R>() : null;
|
||||
destination[i++] = (item.Protected() - subtrahend).ToUnit<R>();
|
||||
}
|
||||
internal static void Minus<T, R>(this double minuend, IReadOnlyCollection<T> units, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R>() : null;
|
||||
destination[i++] = (minuend - item.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> + yeild ===
|
||||
@@ -344,8 +340,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value.ToDouble() - subtrahend).ToUnit<R>() : null;
|
||||
yield return (item.Protected() - subtrahend).ToUnit<R>();
|
||||
}
|
||||
static IEnumerable<R> MinusIterator<T, R>(double minuend, IEnumerable<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -359,8 +354,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (minuend - item.Value.ToDouble()).ToUnit<R>() : null;
|
||||
yield return (minuend - item.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -374,7 +368,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Minus(subtrahend, arr);
|
||||
arr.MinusCore(subtrahend, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return MinusIterator<T, R>(units, subtrahend);
|
||||
@@ -389,7 +383,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Minus(subtrahend, arr);
|
||||
arr.MinusCore(subtrahend, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return MinusNullableIterator<T, R>(units, subtrahend);
|
||||
@@ -404,7 +398,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
minuend.Minus(arr, arr);
|
||||
minuend.MinusCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return MinusIterator<T, R>(minuend, units);
|
||||
@@ -419,7 +413,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
minuend.Minus(arr, arr);
|
||||
minuend.MinusCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return MinusNullableIterator<T, R>(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<T>(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<T>(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<T>(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<T>
|
||||
{
|
||||
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<T, T>();
|
||||
var result = new T[count];
|
||||
CollectionsMarshal.AsSpan(units).MinusCore(subtrahend, count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Minus<T>(this List<T?> units, double subtrahend)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
CollectionsMarshal.AsSpan(units).MinusCore(subtrahend, count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T> Minus<T>(this double minuend, List<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T[count];
|
||||
minuend.MinusCore(CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Minus<T>(this double minuend, List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
minuend.MinusCore(CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<T> ===
|
||||
@@ -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<T> list) { CollectionsMarshal.AsSpan(list).Minus(subtrahend, destination); return; }
|
||||
if (units is T[] array) { array.MinusCore(subtrahend, count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { CollectionsMarshal.AsSpan(list).Minus(subtrahend, destination); return; }
|
||||
if (units is T?[] array) { array.MinusCore(subtrahend, count, destination); return; }
|
||||
if (units is List<T?> 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<T>() : null;
|
||||
destination[i++] = (item.Protected() - subtrahend).ToUnit<T>();
|
||||
}
|
||||
internal static void Minus<T>(this double minuend, IReadOnlyCollection<T> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T> list) { minuend.Minus(CollectionsMarshal.AsSpan(list), destination); return; }
|
||||
if (units is T[] array) { minuend.MinusCore(array, count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { minuend.Minus(CollectionsMarshal.AsSpan(list), destination); return; }
|
||||
if (units is T?[] array) { minuend.MinusCore(array, count, destination); return; }
|
||||
if (units is List<T?> 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<T>() : null;
|
||||
destination[i++] = (minuend - item.Protected()).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> + yeild ===
|
||||
@@ -643,8 +635,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value.ToDouble() - subtrahend).ToUnit<T>() : null;
|
||||
yield return (item.Protected() - subtrahend).ToUnit<T>();
|
||||
}
|
||||
static IEnumerable<T> MinusIterator<T>(double minuend, IEnumerable<T> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -656,8 +647,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (minuend - item.Value.ToDouble()).ToUnit<T>() : null;
|
||||
yield return (minuend - item.Protected()).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -670,7 +660,7 @@ internal static partial class CollectionsMinusExtensions
|
||||
if (units is IReadOnlyCollection<T> 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<T?> 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<T> 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<T?> 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<R>() : null;
|
||||
d1 = u1.HasValue ? (u1.Value - subtrahend).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (u2.Value - subtrahend).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (u3.Value - subtrahend).ToUnit<R>() : null;
|
||||
d0 = ((u0 ?? 0d) - subtrahend).ToUnit<R>();
|
||||
d1 = ((u1 ?? 0d) - subtrahend).ToUnit<R>();
|
||||
d2 = ((u2 ?? 0d) - subtrahend).ToUnit<R>();
|
||||
d3 = ((u3 ?? 0d) - subtrahend).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = ((unit ?? 0d) - subtrahend).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
//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<R>() : null;
|
||||
d1 = u1.HasValue ? (minuend - u1.Value).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (minuend - u2.Value).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (minuend - u3.Value).ToUnit<R>() : null;
|
||||
d0 = (minuend - (u0 ?? 0d)).ToUnit<R>();
|
||||
d1 = (minuend - (u1 ?? 0d)).ToUnit<R>();
|
||||
d2 = (minuend - (u2 ?? 0d)).ToUnit<R>();
|
||||
d3 = (minuend - (u3 ?? 0d)).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = (minuend - (unit ?? 0d)).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === DivideCore === SIMD
|
||||
// === DivCore === SIMD
|
||||
internal static void MinusCore(this ReadOnlySpan<double> srcDouble, double subtrahend, int len, Span<double> dstDouble)
|
||||
{
|
||||
var vectorizedSubtrahend = new Vector<double>(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<T>(this ReadOnlySpan<double> units, T divisor, Span<T> destination)
|
||||
internal static void Minus<T>(this ReadOnlySpan<double> units, T subtrahend, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T>(this ReadOnlySpan<double?> units, T divisor, Span<T?> destination)
|
||||
internal static void Minus<T>(this ReadOnlySpan<double?> units, T subtrahend, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T>(this T dividend, ReadOnlySpan<double> units, Span<T> destination)
|
||||
internal static void Minus<T>(this T minuend, ReadOnlySpan<double> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T>(this T dividend, ReadOnlySpan<double?> units, Span<T?> destination)
|
||||
internal static void Minus<T>(this T minuend, ReadOnlySpan<double?> units, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T>(this double[] units, T divisor)
|
||||
internal static T[] Minus<T>(this double[] units, T subtrahend)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T>(this double?[] units, T divisor)
|
||||
internal static T?[] Minus<T>(this double?[] units, T subtrahend)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T>(this T dividend, double[] units)
|
||||
internal static T[] Minus<T>(this T minuend, double[] units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T>(this T dividend, double?[] units)
|
||||
internal static T?[] Minus<T>(this T minuend, double?[] units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T> ===
|
||||
internal static List<T> Minus<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];
|
||||
Minus(CollectionsMarshal.AsSpan(units), divisor, resultArray);
|
||||
return resultArray.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Minus<T>(this List<double?> units, T divisor)
|
||||
internal static List<T> Minus<T>(this List<double> units, T subtrahend)
|
||||
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];
|
||||
Minus(CollectionsMarshal.AsSpan(units), divisor, resultArray);
|
||||
return resultArray.WrapAsList<T, T>();
|
||||
var result = new T[count];
|
||||
CollectionsMarshal.AsSpan(units).MinusCore(subtrahend.ToDouble(), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T> Minus<T>(this T dividend, List<double> units)
|
||||
internal static List<T?> Minus<T>(this List<double?> units, T subtrahend)
|
||||
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];
|
||||
Minus(dividend, CollectionsMarshal.AsSpan(units), resultArray);
|
||||
return resultArray.WrapAsList<T, T>();
|
||||
var result = new T?[count];
|
||||
CollectionsMarshal.AsSpan(units).MinusCore(subtrahend.ToDouble(), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Minus<T>(this T dividend, List<double?> units)
|
||||
internal static List<T> Minus<T>(this T minuend, 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];
|
||||
Minus(dividend, CollectionsMarshal.AsSpan(units), resultArray);
|
||||
return resultArray.WrapAsList<T, T>();
|
||||
var result = new T[count];
|
||||
minuend.ToDouble().MinusCore(CollectionsMarshal.AsSpan(units), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Minus<T>(this T minuend, List<double?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<T, T>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<T> ===
|
||||
internal static void Minus<T>(this IReadOnlyCollection<double> units, T divisor, Span<T> destination)
|
||||
internal static void Minus<T>(this IReadOnlyCollection<double> units, T subtrahend, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<double> list) { CollectionsMarshal.AsSpan(list).Minus(divisor, destination); return; }
|
||||
if (units is double[] array) { array.MinusCore(subtrahend.ToDouble(), count, destination); return; }
|
||||
if (units is List<double> 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<T>();
|
||||
}
|
||||
internal static void Minus<T>(this IReadOnlyCollection<double?> units, T divisor, Span<T?> destination)
|
||||
internal static void Minus<T>(this IReadOnlyCollection<double?> units, T subtrahend, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<double?> list) { CollectionsMarshal.AsSpan(list).Minus(divisor, destination); return; }
|
||||
if (units is double?[] array) { array.MinusCore(subtrahend.ToDouble(), count, destination); return; }
|
||||
if (units is List<double?> 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<T>() : null;
|
||||
destination[i++] = ((item ?? 0d) * invMinusisor).ToUnit<T>();
|
||||
}
|
||||
internal static void Minus<T>(this T dividend, IReadOnlyCollection<double> units, Span<T> destination)
|
||||
internal static void Minus<T>(this T minuend, IReadOnlyCollection<double> units, Span<T> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<double> list) { dividend.Minus(CollectionsMarshal.AsSpan(list), destination); return; }
|
||||
if (units is double[] array) { minuend.ToDouble().MinusCore(array, count, destination); return; }
|
||||
if (units is List<double> 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<T>();
|
||||
destination[i++] = (div / item).ToUnit<T>();
|
||||
}
|
||||
internal static void Minus<T>(this T dividend, IReadOnlyCollection<double?> units, Span<T?> destination)
|
||||
internal static void Minus<T>(this T minuend, IReadOnlyCollection<double?> units, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
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<double?> list) { dividend.Minus(CollectionsMarshal.AsSpan(list), destination); return; }
|
||||
if (units is double?[] array) { minuend.ToDouble().MinusCore(array, count, destination); return; }
|
||||
if (units is List<double?> 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<T>() : null;
|
||||
destination[i++] = (div / (item ?? 0d)).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> + yeild ===
|
||||
static IEnumerable<T> MinusideIterator<T>(IEnumerable<double> units, double divisor)
|
||||
static IEnumerable<T> MinusideIterator<T>(IEnumerable<double> units, double subtrahend)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
double invMinusisor = 1.0 / divisor;
|
||||
double invMinusisor = 1.0 / subtrahend;
|
||||
foreach (var item in units)
|
||||
yield return (item * invMinusisor).ToUnit<T>();
|
||||
}
|
||||
static IEnumerable<T?> MinusideNullableIterator<T>(IEnumerable<double?> units, double divisor)
|
||||
static IEnumerable<T?> MinusideNullableIterator<T>(IEnumerable<double?> units, double subtrahend)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
double invMinusisor = 1.0 / divisor;
|
||||
double invMinusisor = 1.0 / subtrahend;
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value * invMinusisor).ToUnit<T>() : null;
|
||||
yield return ((item ?? 0d) * invMinusisor).ToUnit<T>();
|
||||
}
|
||||
static IEnumerable<T> MinusideIterator<T>(double dividend, IEnumerable<double> units)
|
||||
static IEnumerable<T> MinusideIterator<T>(double minuend, IEnumerable<double> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return (dividend / item).ToUnit<T>();
|
||||
yield return (minuend / item).ToUnit<T>();
|
||||
}
|
||||
static IEnumerable<T?> MinusideNullableIterator<T>(double dividend, IEnumerable<double?> units)
|
||||
static IEnumerable<T?> MinusideNullableIterator<T>(double minuend, IEnumerable<double?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? (dividend / item.Value).ToUnit<T>() : null;
|
||||
yield return (minuend / (item ?? 0d)).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
internal static IEnumerable<T> Minus<T>(this IEnumerable<double> units, T divisor)
|
||||
internal static IEnumerable<T> Minus<T>(this IEnumerable<double> units, T subtrahend)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
if (units is double[] array) return array.Minus(divisor);
|
||||
if (units is List<double> list) return list.Minus(divisor);
|
||||
if (units is double[] array) return array.Minus(subtrahend);
|
||||
if (units is List<double> list) return list.Minus(subtrahend);
|
||||
if (units is IReadOnlyCollection<double> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.MinusCore(divisor.ToDouble(), arr.Length, arr);
|
||||
arr.MinusCore(subtrahend.ToDouble(), arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return MinusideIterator<T>(units, divisor.ToDouble());
|
||||
return MinusideIterator<T>(units, subtrahend.ToDouble());
|
||||
}
|
||||
internal static IEnumerable<T?> Minus<T>(this IEnumerable<double?> units, T divisor)
|
||||
internal static IEnumerable<T?> Minus<T>(this IEnumerable<double?> units, T subtrahend)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
if (units is double?[] array) return array.Minus(divisor);
|
||||
if (units is List<double?> list) return list.Minus(divisor);
|
||||
if (units is double?[] array) return array.Minus(subtrahend);
|
||||
if (units is List<double?> list) return list.Minus(subtrahend);
|
||||
if (units is IReadOnlyCollection<double?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.MinusCore(divisor.ToDouble(), arr.Length, arr);
|
||||
arr.MinusCore(subtrahend.ToDouble(), arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return MinusideNullableIterator<T>(units, divisor.ToDouble());
|
||||
return MinusideNullableIterator<T>(units, subtrahend.ToDouble());
|
||||
}
|
||||
internal static IEnumerable<T> Minus<T>(this T dividend, IEnumerable<double> units)
|
||||
internal static IEnumerable<T> Minus<T>(this T minuend, IEnumerable<double> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
if (units is double[] array) return dividend.Minus(array);
|
||||
if (units is List<double> list) return dividend.Minus(list);
|
||||
if (units is double[] array) return minuend.Minus(array);
|
||||
if (units is List<double> list) return minuend.Minus(list);
|
||||
if (units is IReadOnlyCollection<double> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
dividend.ToDouble().MinusCore(arr, arr.Length, arr);
|
||||
minuend.ToDouble().MinusCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return MinusideIterator<T>(dividend.ToDouble(), units);
|
||||
return MinusideIterator<T>(minuend.ToDouble(), units);
|
||||
}
|
||||
internal static IEnumerable<T?> Minus<T>(this T dividend, IEnumerable<double?> units)
|
||||
internal static IEnumerable<T?> Minus<T>(this T minuend, IEnumerable<double?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
if (units is null) return null!;
|
||||
if (units is double?[] array) return dividend.Minus(array);
|
||||
if (units is List<double?> list) return dividend.Minus(list);
|
||||
if (units is double?[] array) return minuend.Minus(array);
|
||||
if (units is List<double?> list) return minuend.Minus(list);
|
||||
if (units is IReadOnlyCollection<double?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
dividend.ToDouble().MinusCore(arr, arr.Length, arr);
|
||||
minuend.ToDouble().MinusCore(arr, arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return MinusideNullableIterator<T>(dividend.ToDouble(), units);
|
||||
return MinusideNullableIterator<T>(minuend.ToDouble(), units);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
internal static partial class CollectionsMultiplyExtensions
|
||||
{
|
||||
// === MultiplyCore === SIMD
|
||||
internal static void MultiplyCore<T, R>(this ReadOnlySpan<T> units, double multiplicator, int len, Span<R> destination)
|
||||
// === MulCore === SIMD
|
||||
internal static void MulCore<T, R>(this ReadOnlySpan<T> units, double multiplicator, int len, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -35,7 +35,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * multiplicator;
|
||||
}
|
||||
}
|
||||
internal static void MultiplyCore<T, R>(this ReadOnlySpan<T?> units, double multiplicator, int len, Span<R?> destination)
|
||||
internal static void MulCore<T, R>(this ReadOnlySpan<T?> units, double multiplicator, int len, Span<R?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -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<R>() : null;
|
||||
d1 = u1.HasValue ? (u1.Value.ToDouble() * multiplicator).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (u2.Value.ToDouble() * multiplicator).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (u3.Value.ToDouble() * multiplicator).ToUnit<R>() : null;
|
||||
d0 = (u0.Protected() * multiplicator).ToUnit<R>();
|
||||
d1 = (u1.Protected() * multiplicator).ToUnit<R>();
|
||||
d2 = (u2.Protected() * multiplicator).ToUnit<R>();
|
||||
d3 = (u3.Protected() * multiplicator).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = (unit.Protected() * multiplicator).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void MultiplyCore<T, R>(this double multiplicator, ReadOnlySpan<T> units, int len, Span<R> destination)
|
||||
internal static void MulCore<T, R>(this double multiplicator, ReadOnlySpan<T> units, int len, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R> => units.MultiplyCore(multiplicator, len, destination);
|
||||
where R : struct, IMensuraUnit, IEquatable<R> => units.MulCore(multiplicator, len, destination);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void MultiplyCore<T, R>(this double multiplicator, ReadOnlySpan<T?> units, int len, Span<R?> destination)
|
||||
internal static void MulCore<T, R>(this double multiplicator, ReadOnlySpan<T?> units, int len, Span<R?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R> => units.MultiplyCore(multiplicator, len, destination);
|
||||
where R : struct, IMensuraUnit, IEquatable<R> => 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<T, R>(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<R, R>();
|
||||
var result = new R[count];
|
||||
MulCore(CollectionsMarshal.AsSpan(units), multiplicator, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Mul<T, R>(this List<T?> units, double multiplicator)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
MulCore(CollectionsMarshal.AsSpan(units), multiplicator, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
[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<T> list) { MultiplyCore(CollectionsMarshal.AsSpan(list), multiplicator, count, destination); return; }
|
||||
if (units is T[] array) { MulCore(array, multiplicator, count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { MultiplyCore(CollectionsMarshal.AsSpan(list), multiplicator, count, destination); return; }
|
||||
if (units is T?[] array) { MulCore(array, multiplicator, count, destination); return; }
|
||||
if (units is List<T?> 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<R>() : null;
|
||||
destination[i++] = (item.Protected() * multiplicator).ToUnit<R>();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -222,8 +220,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value.ToDouble() * multiplicator).ToUnit<R>() : null;
|
||||
yield return (item.Protected() * multiplicator).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -237,7 +234,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Mul(multiplicator, arr);
|
||||
arr.MulCore(multiplicator, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return MultiplyIterator<T, R>(units, multiplicator);
|
||||
@@ -252,7 +249,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Mul(multiplicator, arr);
|
||||
arr.MulCore(multiplicator, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return MultiplyNullableIterator<T, R>(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<T>(this ReadOnlySpan<T?> units, double multiplicator, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>(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<T>
|
||||
{
|
||||
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<T, T>();
|
||||
var result = new T[count];
|
||||
CollectionsMarshal.AsSpan(units).MulCore(multiplicator, count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Mul<T>(this List<T?> units, double multiplicator)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
CollectionsMarshal.AsSpan(units).MulCore(multiplicator, count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
|
||||
[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<T> list) { CollectionsMarshal.AsSpan(list).Mul(multiplicator, destination); return; }
|
||||
if (units is T[] array) { array.MulCore(multiplicator, array.Length, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { CollectionsMarshal.AsSpan(list).Mul(multiplicator, destination); return; }
|
||||
if (units is T?[] array) { array.MulCore(multiplicator, array.Length, destination); return; }
|
||||
if (units is List<T?> 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<T>() : null;
|
||||
destination[i++] = (item.Protected() * multiplicator).ToUnit<T>();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -419,8 +415,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value.ToDouble() * multiplicator).ToUnit<T>() : null;
|
||||
yield return (item.Protected() * multiplicator).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -433,7 +428,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
if (units is IReadOnlyCollection<T> 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<T?> 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<R>(this ReadOnlySpan<double> srcDouble, double multiplicator, int len, Span<R> destination)
|
||||
// === MulCore === SIMD
|
||||
internal static void MulCore<R>(this ReadOnlySpan<double> srcDouble, double multiplicator, int len, Span<R> destination)
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
Span<double> dstDouble = MemoryMarshal.Cast<R, double>(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<R>(this ReadOnlySpan<double?> units, double multiplicator, int len, Span<R?> destination)
|
||||
internal static void MulCore<R>(this ReadOnlySpan<double?> units, double multiplicator, int len, Span<R?> destination)
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
// Получаем прямые неуправляемые 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<R>() : null;
|
||||
d1 = u1.HasValue ? (u1.Value * multiplicator).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (u2.Value * multiplicator).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (u3.Value * multiplicator).ToUnit<R>() : null;
|
||||
d0 = ((u0 ?? 0d) * multiplicator).ToUnit<R>();
|
||||
d1 = ((u1 ?? 0d) * multiplicator).ToUnit<R>();
|
||||
d2 = ((u2 ?? 0d) * multiplicator).ToUnit<R>();
|
||||
d3 = ((u3 ?? 0d) * multiplicator).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = ((unit ?? 0d) * multiplicator).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MultiplyCore<R>(this double multiplicator, ReadOnlySpan<double> units,
|
||||
int len, Span<R> destination) where R : struct, IMensuraUnit, IEquatable<R> => units.MultiplyCore(multiplicator, len, destination);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MultiplyCore<R>(this double multiplicator, ReadOnlySpan<double?> units,
|
||||
int len, Span<R?> destination) where R : struct, IMensuraUnit, IEquatable<R> => units.MultiplyCore(multiplicator, len, destination);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MulCore<R>(this double multiplicator, ReadOnlySpan<double> units,
|
||||
int len, Span<R> destination) where R : struct, IMensuraUnit, IEquatable<R> => units.MulCore(multiplicator, len, destination);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MulCore<R>(this double multiplicator, ReadOnlySpan<double?> units,
|
||||
int len, Span<R?> destination) where R : struct, IMensuraUnit, IEquatable<R> => units.MulCore(multiplicator, len, destination);
|
||||
|
||||
|
||||
// === MultiplyCore === SIMD
|
||||
internal static void MultiplyCore(this ReadOnlySpan<double> srcDouble, double multiplicator, int len, Span<double> dstDouble)
|
||||
// === MulCore === SIMD
|
||||
internal static void MulCore(this ReadOnlySpan<double> srcDouble, double multiplicator, int len, Span<double> dstDouble)
|
||||
{
|
||||
var vectorizedMultiplicator = new Vector<double>(multiplicator);
|
||||
int vectorSize = Vector<double>.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<double?> units, double multiplicator, int len, Span<double?> destination)
|
||||
internal static void MulCore(this ReadOnlySpan<double?> units, double multiplicator, int len, Span<double?> 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<double> units, int len, Span<double> destination) => units.MultiplyCore(multiplicator, len, destination);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MultiplyCore(this double multiplicator,
|
||||
ReadOnlySpan<double?> units, int len, Span<double?> destination) => units.MultiplyCore(multiplicator, len, destination);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MulCore(this double multiplicator,
|
||||
ReadOnlySpan<double> units, int len, Span<double> destination) => units.MulCore(multiplicator, len, destination);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void MulCore(this double multiplicator,
|
||||
ReadOnlySpan<double?> units, int len, Span<double?> 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<T>(this ReadOnlySpan<double?> units, T multiplicator, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T>(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<T>
|
||||
{
|
||||
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<T, T>();
|
||||
var result = new T[count];
|
||||
CollectionsMarshal.AsSpan(units).MulCore(multiplicator.ToDouble(), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Mul<T>(this List<double?> units, T multiplicator)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
CollectionsMarshal.AsSpan(units).MulCore(multiplicator.ToDouble(), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
|
||||
[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<double> 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<double> 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<T>();
|
||||
destination[i++] = (item * mul).ToUnit<T>();
|
||||
}
|
||||
internal static void Mul<T>(this IReadOnlyCollection<double?> units, T multiplicator, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<double?> 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<double?> 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<T>() : null;
|
||||
destination[i++] = ((item ?? 0d) * mul).ToUnit<T>();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -772,8 +767,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value * multiplicator).ToUnit<T>() : null;
|
||||
yield return ((item ?? 0d) * multiplicator).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -786,7 +780,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
if (units is IReadOnlyCollection<double> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.MultiplyCore(multiplicator.ToDouble(), arr.Length, arr);
|
||||
arr.MulCore(multiplicator.ToDouble(), arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return MultiplyIterator<T>(units, multiplicator.ToDouble());
|
||||
@@ -800,7 +794,7 @@ internal static partial class CollectionsMultiplyExtensions
|
||||
if (units is IReadOnlyCollection<double?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.MultiplyCore(multiplicator.ToDouble(), arr.Length, arr);
|
||||
arr.MulCore(multiplicator.ToDouble(), arr.Length, arr);
|
||||
return arr.ReCast<T>();
|
||||
}
|
||||
return MultiplyNullableIterator<T>(units, multiplicator.ToDouble());
|
||||
|
||||
@@ -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<R>() : null;
|
||||
d1 = u1.HasValue ? (u1.Value.ToDouble() + summand).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (u2.Value.ToDouble() + summand).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (u3.Value.ToDouble() + summand).ToUnit<R>() : null;
|
||||
d0 = (u0.Protected() + summand).ToUnit<R>();
|
||||
d1 = (u1.Protected() + summand).ToUnit<R>();
|
||||
d2 = (u2.Protected() + summand).ToUnit<R>();
|
||||
d3 = (u3.Protected() + summand).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = (unit.Protected() + summand).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<R, R>();
|
||||
var result = new R[count];
|
||||
PlusCore(CollectionsMarshal.AsSpan(units), summand, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Plus<T, R>(this List<T?> units, double summand)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
PlusCore(CollectionsMarshal.AsSpan(units), summand, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
[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<R>() : null;
|
||||
destination[i++] = (item.Protected() + summand).ToUnit<R>();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -223,8 +221,7 @@ internal static partial class CollectionsPlusExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value.ToDouble() + summand).ToUnit<R>() : null;
|
||||
yield return (item.Protected() + summand).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -238,7 +235,7 @@ internal static partial class CollectionsPlusExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Plus(summand, arr);
|
||||
arr.PlusCore(summand, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return PlusIterator<T, R>(units, summand);
|
||||
@@ -253,7 +250,7 @@ internal static partial class CollectionsPlusExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Plus(summand, arr);
|
||||
arr.PlusCore(summand, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
return PlusNullableIterator<T, R>(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<T>(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<T>
|
||||
{
|
||||
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<T, T>();
|
||||
var result = new T[count];
|
||||
CollectionsMarshal.AsSpan(units).PlusCore(summand, count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Plus<T>(this List<T?> units, double summand)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
CollectionsMarshal.AsSpan(units).PlusCore(summand, count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
|
||||
[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<T> list) { CollectionsMarshal.AsSpan(list).Plus(summand, destination); return; }
|
||||
if (units is T[] array) { array.PlusCore(summand, count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { CollectionsMarshal.AsSpan(list).Plus(summand, destination); return; }
|
||||
if (units is T?[] array) { array.PlusCore(summand, count, destination); return; }
|
||||
if (units is List<T?> 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<T>() : null;
|
||||
destination[i++] = (item.Protected() + summand).ToUnit<T>();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -420,8 +416,7 @@ internal static partial class CollectionsPlusExtensions
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (T? item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value.ToDouble() + summand).ToUnit<T>() : null;
|
||||
yield return (item.Protected() + summand).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
@@ -434,7 +429,7 @@ internal static partial class CollectionsPlusExtensions
|
||||
if (units is IReadOnlyCollection<T> 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<T?> 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<R>() : null;
|
||||
d1 = u1.HasValue ? (u1.Value + summand).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? (u2.Value + summand).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? (u3.Value + summand).ToUnit<R>() : null;
|
||||
d0 = ((u0 ?? 0d) + summand).ToUnit<R>();
|
||||
d1 = ((u1 ?? 0d) + summand).ToUnit<R>();
|
||||
d2 = ((u2 ?? 0d) + summand).ToUnit<R>();
|
||||
d3 = ((u3 ?? 0d) + summand).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = ((unit ?? 0d) + summand).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T>(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<T>
|
||||
{
|
||||
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<T, T>();
|
||||
var result = new T[count];
|
||||
CollectionsMarshal.AsSpan(units).PlusCore(summand.ToDouble(), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
internal static List<T?> Plus<T>(this List<double?> units, T summand)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, T>();
|
||||
var result = new T?[count];
|
||||
CollectionsMarshal.AsSpan(units).PlusCore(summand.ToDouble(), count, result);
|
||||
return result.WrapAsList<T, T>();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -737,8 +730,9 @@ internal static partial class CollectionsPlusExtensions
|
||||
if (units is List<double> 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<T>();
|
||||
destination[i++] = (item + sum).ToUnit<T>();
|
||||
}
|
||||
internal static void Plus<T>(this IReadOnlyCollection<double?> units, T summand, Span<T?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -753,9 +747,9 @@ internal static partial class CollectionsPlusExtensions
|
||||
if (units is List<double?> 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<T>() : null;
|
||||
destination[i++] = ((item ?? 0d) + sum).ToUnit<T>();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -777,8 +771,7 @@ internal static partial class CollectionsPlusExtensions
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? (item.Value + summand).ToUnit<T>() : null;
|
||||
yield return ((item ?? 0d) + summand).ToUnit<T>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
|
||||
@@ -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<T, R>(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<R, R>();
|
||||
var result = new R[count];
|
||||
CollectionsMarshal.AsSpan(units).Pow2Core(count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Pow2<T, R>(this List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
CollectionsMarshal.AsSpan(units).Pow2Core(count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<Length> ===
|
||||
@@ -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<T> list) { CollectionsMarshal.AsSpan(list).Pow2(destination); return; }
|
||||
if (units is T[] array) { array.Pow2Core(count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { CollectionsMarshal.AsSpan(list).Pow2(destination); return; }
|
||||
if (units is T?[] array) { array.Pow2Core(count, destination); return; }
|
||||
if (units is List<T?> 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<R>() : null;
|
||||
destination[i++] = item.Protected().QuickPow2().ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T, R> + yeild ===
|
||||
@@ -222,8 +221,7 @@ internal static partial class CollectionsPow2Extensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? item.Value.ToDouble().QuickPow2().ToUnit<R>() : null;
|
||||
yield return item.Protected().QuickPow2().ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<Length> ===
|
||||
@@ -237,7 +235,7 @@ internal static partial class CollectionsPow2Extensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Pow2(arr);
|
||||
arr.Pow2Core(arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return Pow2Iterator<T, R>(units);
|
||||
@@ -252,7 +250,7 @@ internal static partial class CollectionsPow2Extensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Pow2(arr);
|
||||
arr.Pow2Core(arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return Pow2NullableIterator<T, R>(units);
|
||||
|
||||
@@ -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<T, R>(this ReadOnlySpan<T> units, int len, Span<R> destination)
|
||||
// === Pow3Core === SIMD
|
||||
internal static void Pow3Core<T, R>(this ReadOnlySpan<T> units, int len, Span<R> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -46,7 +43,7 @@ internal static partial class CollectionsPow3Extensions
|
||||
dstDouble[i] = val * val * val;
|
||||
}
|
||||
}
|
||||
internal static void PowCore3<T, R>(this ReadOnlySpan<T?> units, int len, Span<R?> destination)
|
||||
internal static void Pow3Core<T, R>(this ReadOnlySpan<T?> units, int len, Span<R?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
@@ -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<T, R>(this ReadOnlySpan<T?> units, Span<R?> destination)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<T, R>(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<R, R>();
|
||||
var result = new R[count];
|
||||
CollectionsMarshal.AsSpan(units).Pow3Core(count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Pow3<T, R>(this List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
CollectionsMarshal.AsSpan(units).Pow3Core(count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<Length> ===
|
||||
@@ -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<T> list) { CollectionsMarshal.AsSpan(list).Pow3(destination); return; }
|
||||
if (units is T[] array) { array.Pow3Core(count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { CollectionsMarshal.AsSpan(list).Pow3(destination); return; }
|
||||
if (units is T?[] array) { array.Pow3Core(count, destination); return; }
|
||||
if (units is List<T?> 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<R>() : null;
|
||||
destination[i++] = item.Protected().QuickPow3().ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T, R> + yeild ===
|
||||
@@ -225,8 +221,7 @@ internal static partial class CollectionsPow3Extensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? item.Value.ToDouble().QuickPow3().ToUnit<R>() : null;
|
||||
yield return item.Protected().QuickPow3().ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<Length> ===
|
||||
@@ -240,7 +235,7 @@ internal static partial class CollectionsPow3Extensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Pow3(arr);
|
||||
arr.Pow3Core(arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return PowIterator3<T, R>(units);
|
||||
@@ -255,7 +250,7 @@ internal static partial class CollectionsPow3Extensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Pow3(arr);
|
||||
arr.Pow3Core(arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return PowNullableIterator3<T, R>(units);
|
||||
|
||||
@@ -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<R>() : null;
|
||||
d1 = u1.HasValue ? u1.Value.ToDouble().QuickPow(power).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? u2.Value.ToDouble().QuickPow(power).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? u3.Value.ToDouble().QuickPow(power).ToUnit<R>() : null;
|
||||
d0 = u0.Protected().QuickPow(power).ToUnit<R>();
|
||||
d1 = u1.Protected().QuickPow(power).ToUnit<R>();
|
||||
d2 = u2.Protected().QuickPow(power).ToUnit<R>();
|
||||
d3 = u3.Protected().QuickPow(power).ToUnit<R>();
|
||||
}
|
||||
|
||||
// 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<R>() : null;
|
||||
dst = unit.Protected().QuickPow(power).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T, R>(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<R, R>();
|
||||
var result = new R[count];
|
||||
CollectionsMarshal.AsSpan(units).PowCore(power, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Pow<T, R>(this List<T?> units, int power)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
@@ -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<R, R>();
|
||||
var result = new R?[count];
|
||||
CollectionsMarshal.AsSpan(units).PowCore(power, count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
// === IReadOnlyCollection<Length> ===
|
||||
@@ -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<T> list) { CollectionsMarshal.AsSpan(list).Pow(power, destination); return; }
|
||||
if (units is T[] array) { array.PowCore(power, count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { CollectionsMarshal.AsSpan(list).Pow(power, destination); return; }
|
||||
if (units is T?[] array) { array.PowCore(power, count, destination); return; }
|
||||
if (units is List<T?> 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<R>() : null;
|
||||
destination[i++] = item.Protected().QuickPow(power).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<T, R> + yeild ===
|
||||
@@ -272,8 +271,7 @@ internal static partial class CollectionsPowNExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? item.Value.ToDouble().QuickPow(power).ToUnit<R>() : null;
|
||||
yield return item.Protected().QuickPow(power).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<Length> ===
|
||||
@@ -287,7 +285,7 @@ internal static partial class CollectionsPowNExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Pow(power, arr);
|
||||
arr.PowCore(power, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return PowIterator<T, R>(units, power);
|
||||
@@ -302,7 +300,7 @@ internal static partial class CollectionsPowNExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Pow(power, arr);
|
||||
arr.PowCore(power, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return PowNullableIterator<T, R>(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<R>();
|
||||
dst = Math.Pow(item.Protected(), power).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<T, R>(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<R>
|
||||
{
|
||||
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<R, R>();
|
||||
}
|
||||
internal static List<R?> Pow<T, R>(this List<T?> units, double power)
|
||||
@@ -477,11 +475,11 @@ internal static partial class CollectionsPowNExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
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<R, R>();
|
||||
}
|
||||
|
||||
@@ -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<T> list) { CollectionsMarshal.AsSpan(list).Pow(power, destination); return; }
|
||||
if (units is T[] array) { array.PowCore(power, count, destination); return; }
|
||||
if (units is List<T> 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<T?> list) { CollectionsMarshal.AsSpan(list).Pow(power, destination); return; }
|
||||
if (units is T?[] array) { array.PowCore(power, count, destination); return; }
|
||||
if (units is List<T?> 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<R>() : null;
|
||||
destination[i++] = Math.Pow(item.Protected(), power).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<Length> + yield ===
|
||||
@@ -535,8 +532,7 @@ internal static partial class CollectionsPowNExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? Math.Pow(item.Value.ToDouble(), power).ToUnit<R>() : null;
|
||||
yield return Math.Pow(item.Protected(), power).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable<Length> ===
|
||||
@@ -550,7 +546,7 @@ internal static partial class CollectionsPowNExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Pow(power, arr);
|
||||
arr.PowCore(power, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return PowIterator<T, R>(units, power);
|
||||
@@ -565,7 +561,7 @@ internal static partial class CollectionsPowNExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Pow(power, arr);
|
||||
arr.PowCore(power, arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return PowNullableIterator<T, R>(units, power);
|
||||
|
||||
@@ -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<R>() : 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<R>() : 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<R>() : 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<R>() : null;
|
||||
Unsafe.Add(ref dstRef, i) = Math.Sqrt(Unsafe.Add(ref srcRef, i)!.Protected()).ToUnit<R>();
|
||||
Unsafe.Add(ref dstRef, i + 1) = Math.Sqrt(Unsafe.Add(ref srcRef, i + 1)!.Protected()).ToUnit<R>();
|
||||
Unsafe.Add(ref dstRef, i + 2) = Math.Sqrt(Unsafe.Add(ref srcRef, i + 2)!.Protected()).ToUnit<R>();
|
||||
Unsafe.Add(ref dstRef, i + 3) = Math.Sqrt(Unsafe.Add(ref srcRef, i + 3)!.Protected()).ToUnit<R>();
|
||||
}
|
||||
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<R>() : null;
|
||||
Unsafe.Add(ref dstRef, i) = Math.Sqrt(Unsafe.Add(ref srcRef, i)!.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === ReadOnlySpan ===
|
||||
@@ -85,10 +85,11 @@ internal static partial class CollectionsRootOfCubeExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
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<T, R>(this T?[] units)
|
||||
@@ -96,10 +97,11 @@ internal static partial class CollectionsRootOfCubeExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
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<R>
|
||||
{
|
||||
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<R, R>();
|
||||
var result = new R[count];
|
||||
CollectionsMarshal.AsSpan(units).CbrtCore(count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Cbrt<T, R>(this List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
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<R, R>();
|
||||
var result = new R?[count];
|
||||
CollectionsMarshal.AsSpan(units).CbrtCore(count, result);
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
// === 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<T?> list) { CollectionsMarshal.AsSpan(list).Cbrt(destination); return; }
|
||||
if (units is T?[] array) { array.CbrtCore(count, destination); return; }
|
||||
if (units is List<T?> 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<R>() : null;
|
||||
destination[i++] = Math.Sqrt(item.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable + yield ===
|
||||
@@ -177,8 +178,7 @@ internal static partial class CollectionsRootOfCubeExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? Math.Sqrt(item.Value.ToDouble()).ToUnit<R>() : null;
|
||||
yield return Math.Sqrt(item.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable ===
|
||||
@@ -192,7 +192,7 @@ internal static partial class CollectionsRootOfCubeExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Cbrt(arr);
|
||||
arr.CbrtCore(arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return SqrtIterator3<T, R>(units);
|
||||
@@ -207,7 +207,7 @@ internal static partial class CollectionsRootOfCubeExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Cbrt(arr);
|
||||
arr.CbrtCore(arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return SqrtNullableIterator3<T, R>(units);
|
||||
|
||||
@@ -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<R>() : null;
|
||||
d1 = u1.HasValue ? Math.Sqrt(u1.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d2 = u2.HasValue ? Math.Sqrt(u2.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d3 = u3.HasValue ? Math.Sqrt(u3.Value.ToDouble()).ToUnit<R>() : null;
|
||||
d0 = Math.Sqrt(u0.Protected()).ToUnit<R>();
|
||||
d1 = Math.Sqrt(u1.Protected()).ToUnit<R>();
|
||||
d2 = Math.Sqrt(u2.Protected()).ToUnit<R>();
|
||||
d3 = Math.Sqrt(u3.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// ХВОСТ ЦИКЛА: Остаток элементов
|
||||
@@ -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<R>() : null;
|
||||
dst = Math.Sqrt(unit.Protected()).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,24 +146,24 @@ internal static partial class CollectionsRootOfSquareExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
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<R, R>();
|
||||
var result = new R[count];
|
||||
CollectionsMarshal.AsSpan(units).SqrtCore(count, result.AsSpan());
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
internal static List<R?> Sqrt<T, R>(this List<T?> units)
|
||||
where T : struct, IMensuraUnit, IEquatable<T>
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
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<R, R>();
|
||||
var result = new R?[count];
|
||||
CollectionsMarshal.AsSpan(units).SqrtCore(count, result.AsSpan());
|
||||
return result.WrapAsList<R, R>();
|
||||
}
|
||||
|
||||
// === 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<R>() : null;
|
||||
Unsafe.Add(ref dstRef, i++) = Math.Sqrt(item.Protected()).ToUnit<R>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,8 +223,7 @@ internal static partial class CollectionsRootOfSquareExtensions
|
||||
where R : struct, IMensuraUnit, IEquatable<R>
|
||||
{
|
||||
foreach (var item in units)
|
||||
yield return item.HasValue
|
||||
? Math.Sqrt(item.Value.ToDouble()).ToUnit<R>() : null;
|
||||
yield return Math.Sqrt(item.Protected()).ToUnit<R>();
|
||||
}
|
||||
|
||||
// === IEnumerable API ===
|
||||
@@ -239,7 +237,7 @@ internal static partial class CollectionsRootOfSquareExtensions
|
||||
if (units is IReadOnlyCollection<T> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Sqrt(arr);
|
||||
arr.SqrtCore(arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return SqrtIterator<T, R>(units);
|
||||
@@ -254,7 +252,7 @@ internal static partial class CollectionsRootOfSquareExtensions
|
||||
if (units is IReadOnlyCollection<T?> roc)
|
||||
{
|
||||
var arr = roc.ToArray();
|
||||
arr.Sqrt(arr);
|
||||
arr.SqrtCore(arr.Length, arr);
|
||||
return arr.ReCast<T, R>();
|
||||
}
|
||||
else return SqrtNullableIterator<T, R>(units);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
20
QWERTYkez.Mensura/Extensions/EFCoreExtension.cs
Normal file
20
QWERTYkez.Mensura/Extensions/EFCoreExtension.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace QWERTYkez.Mensura.Extensions;
|
||||
|
||||
public static partial class EFCoreExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Регистрирует ValueConverter для всех типов, реализующих IMensuraUnit.
|
||||
/// </summary>
|
||||
public static void UseMensuraUnits(this ModelConfigurationBuilder configurationBuilder)
|
||||
{
|
||||
AddGeneratedConverters(configurationBuilder);
|
||||
AddGeneratedComplexConverters(configurationBuilder);
|
||||
}
|
||||
|
||||
internal class MensuraUnitConverter<U>()
|
||||
: ValueConverter<U, double>(unit => unit.ToDouble(), value => value.ToUnit<U>())
|
||||
where U : struct, IMensuraUnit, IEquatable<U> { }
|
||||
}
|
||||
@@ -9,7 +9,7 @@ internal class ListMimic<T>
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 16)]
|
||||
public struct NullableDoubleMimic
|
||||
internal struct NullableDoubleMimic
|
||||
{
|
||||
[FieldOffset(0)] public bool HasValue;
|
||||
[FieldOffset(8)] public double Value;
|
||||
|
||||
@@ -10,10 +10,18 @@
|
||||
<NoWarn>1701;1702;IDE1006</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\QWERTYkez.Mensura.Generator\QWERTYkez.Mensura.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||
<InternalsVisibleTo Include="QWERTYkez.Mensura.Tests" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" PrivateAssets="All" />
|
||||
<ProjectReference Include="..\QWERTYkez.Mensura.Generator\QWERTYkez.Mensura.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||
<InternalsVisibleTo Include="QWERTYkez.Mensura.Tests" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.36" Condition="'$(TargetFramework)' == 'net6.0'" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" Condition="'$(TargetFramework)' == 'net7.0'" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.28" Condition="'$(TargetFramework)' == 'net8.0'" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.17" Condition="'$(TargetFramework)' == 'net9.0'" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.9" Condition="'$(TargetFramework)' == 'net10.0'" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,70 +1,70 @@
|
||||
#if DEBUG
|
||||
namespace QWERTYkez.Mensura.Units;
|
||||
//#if DEBUG
|
||||
//namespace QWERTYkez.Mensura.Units;
|
||||
|
||||
/// <summary>
|
||||
/// Base value is MilliMeters
|
||||
/// </summary>
|
||||
[DebuggerDisplay("mm = {_MilliMeters.ToString(\"0.###\")}, m = {Meters.ToString(\"0.###\")}")]
|
||||
public readonly partial record struct XXXXXXXX
|
||||
{
|
||||
public static XXXXXXXX MilliMeter { get; } = new(1);
|
||||
[NotMapped, JsonIgnore, IgnoreDataMember] public double _MilliMeters { get => _Value; init => _Value = value; }
|
||||
///// <summary>
|
||||
///// Base value is MilliMeters
|
||||
///// </summary>
|
||||
//[DebuggerDisplay("mm = {_MilliMeters.ToString(\"0.###\")}, m = {Meters.ToString(\"0.###\")}")]
|
||||
//public readonly partial record struct XXXXXXXX
|
||||
//{
|
||||
// public static XXXXXXXX MilliMeter { get; } = new(1);
|
||||
// [NotMapped, JsonIgnore, IgnoreDataMember] public double _MilliMeters { get => _Value; init => _Value = value; }
|
||||
|
||||
|
||||
public static XXXXXXXX CentiMeter { get; } = new(XXXXXXXXConv.CentiMeters.To(1));
|
||||
[NotMapped, JsonIgnore, IgnoreDataMember]
|
||||
public double CentiMeters
|
||||
{
|
||||
get => XXXXXXXXConv.CentiMeters.From(_Value);
|
||||
init
|
||||
{
|
||||
_Value = XXXXXXXXConv.CentiMeters.To(value);
|
||||
}
|
||||
}
|
||||
// public static XXXXXXXX CentiMeter { get; } = new(XXXXXXXXConv.CentiMeters.To(1));
|
||||
// [NotMapped, JsonIgnore, IgnoreDataMember]
|
||||
// public double CentiMeters
|
||||
// {
|
||||
// get => XXXXXXXXConv.CentiMeters.From(_Value);
|
||||
// init
|
||||
// {
|
||||
// _Value = XXXXXXXXConv.CentiMeters.To(value);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static XXXXXXXX DeciMeter { get; } = new(XXXXXXXXConv.DeciMeters.To(1));
|
||||
[NotMapped, JsonIgnore, IgnoreDataMember]
|
||||
public double DeciMeters
|
||||
{
|
||||
get => XXXXXXXXConv.DeciMeters.From(_Value);
|
||||
init => _Value = XXXXXXXXConv.DeciMeters.To(value);
|
||||
}
|
||||
// public static XXXXXXXX DeciMeter { get; } = new(XXXXXXXXConv.DeciMeters.To(1));
|
||||
// [NotMapped, JsonIgnore, IgnoreDataMember]
|
||||
// public double DeciMeters
|
||||
// {
|
||||
// get => XXXXXXXXConv.DeciMeters.From(_Value);
|
||||
// init => _Value = XXXXXXXXConv.DeciMeters.To(value);
|
||||
// }
|
||||
|
||||
public static XXXXXXXX Meter { get; } = new(XXXXXXXXConv.Meters.To(1));
|
||||
[NotMapped, JsonIgnore, IgnoreDataMember]
|
||||
public double Meters
|
||||
{
|
||||
get => XXXXXXXXConv.Meters.From(_Value);
|
||||
init => _Value = XXXXXXXXConv.Meters.To(value);
|
||||
}
|
||||
// public static XXXXXXXX Meter { get; } = new(XXXXXXXXConv.Meters.To(1));
|
||||
// [NotMapped, JsonIgnore, IgnoreDataMember]
|
||||
// public double Meters
|
||||
// {
|
||||
// get => XXXXXXXXConv.Meters.From(_Value);
|
||||
// init => _Value = XXXXXXXXConv.Meters.To(value);
|
||||
// }
|
||||
|
||||
public static XXXXXXXX KiloMeter { get; } = new(XXXXXXXXConv.KiloMeters.To(1));
|
||||
[NotMapped, JsonIgnore, IgnoreDataMember]
|
||||
public double KiloMeters
|
||||
{
|
||||
get => XXXXXXXXConv.KiloMeters.From(_Value);
|
||||
init => _Value = XXXXXXXXConv.KiloMeters.To(value);
|
||||
}
|
||||
// public static XXXXXXXX KiloMeter { get; } = new(XXXXXXXXConv.KiloMeters.To(1));
|
||||
// [NotMapped, JsonIgnore, IgnoreDataMember]
|
||||
// public double KiloMeters
|
||||
// {
|
||||
// get => XXXXXXXXConv.KiloMeters.From(_Value);
|
||||
// init => _Value = XXXXXXXXConv.KiloMeters.To(value);
|
||||
// }
|
||||
|
||||
|
||||
public XXXXXXXX AddMilliMeters(double value) => new(_Value + value);
|
||||
public XXXXXXXX AddCentiMeters(double value) => new(_Value + XXXXXXXXConv.CentiMeters.To(value));
|
||||
public XXXXXXXX AddDeciMeters(double value) => new(_Value + XXXXXXXXConv.DeciMeters.To(value));
|
||||
public XXXXXXXX AddMeters(double value) => new(_Value + XXXXXXXXConv.Meters.To(value));
|
||||
public XXXXXXXX AddKiloMeters(double value) => new(_Value + XXXXXXXXConv.KiloMeters.To(value));
|
||||
}
|
||||
// public XXXXXXXX AddMilliMeters(double value) => new(_Value + value);
|
||||
// public XXXXXXXX AddCentiMeters(double value) => new(_Value + XXXXXXXXConv.CentiMeters.To(value));
|
||||
// public XXXXXXXX AddDeciMeters(double value) => new(_Value + XXXXXXXXConv.DeciMeters.To(value));
|
||||
// public XXXXXXXX AddMeters(double value) => new(_Value + XXXXXXXXConv.Meters.To(value));
|
||||
// public XXXXXXXX AddKiloMeters(double value) => new(_Value + XXXXXXXXConv.KiloMeters.To(value));
|
||||
//}
|
||||
|
||||
|
||||
internal readonly struct XXXXXXXXConv
|
||||
{
|
||||
private XXXXXXXXConv(double multiplicator) => this.Multiplicator = multiplicator;
|
||||
public double To(double value) => value * Multiplicator;
|
||||
public double From(double value) => value / Multiplicator;
|
||||
public double Multiplicator { get; init; }
|
||||
public static XXXXXXXXConv MilliMeters { get; } = new(1);
|
||||
public static XXXXXXXXConv CentiMeters { get; } = new(10);
|
||||
public static XXXXXXXXConv DeciMeters { get; } = new(100);
|
||||
public static XXXXXXXXConv Meters { get; } = new(1000);
|
||||
public static XXXXXXXXConv KiloMeters { get; } = new(1000000);
|
||||
}
|
||||
#endif
|
||||
//internal readonly struct XXXXXXXXConv
|
||||
//{
|
||||
// private XXXXXXXXConv(double multiplicator) => this.Multiplicator = multiplicator;
|
||||
// public double To(double value) => value * Multiplicator;
|
||||
// public double From(double value) => value / Multiplicator;
|
||||
// public double Multiplicator { get; init; }
|
||||
// public static XXXXXXXXConv MilliMeters { get; } = new(1);
|
||||
// public static XXXXXXXXConv CentiMeters { get; } = new(10);
|
||||
// public static XXXXXXXXConv DeciMeters { get; } = new(100);
|
||||
// public static XXXXXXXXConv Meters { get; } = new(1000);
|
||||
// public static XXXXXXXXConv KiloMeters { get; } = new(1000000);
|
||||
//}
|
||||
//#endif
|
||||
Reference in New Issue
Block a user