2660 lines
108 KiB
C#
2660 lines
108 KiB
C#
namespace QWERTYkez.Mensura.Extensions;
|
||
|
||
internal static partial class DoubleExtensions
|
||
{
|
||
internal static double ToDouble(this byte number) => number;
|
||
internal static double ToDouble(this sbyte number) => number;
|
||
internal static double ToDouble(this short number) => number;
|
||
internal static double ToDouble(this ushort number) => number;
|
||
internal static double ToDouble(this int number) => number;
|
||
internal static double ToDouble(this uint number) => number;
|
||
internal static double ToDouble(this nint number) => number;
|
||
internal static double ToDouble(this nuint number) => number;
|
||
internal static double ToDouble(this long number) => number;
|
||
internal static double ToDouble(this ulong number) => number;
|
||
internal static double ToDouble(this Half number) => (double)number;
|
||
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 ?? 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 ?? 0d;
|
||
internal static double ToDouble(this decimal? number) => number.HasValue ? (double)number.Value : 0d;
|
||
|
||
#if NET7_0_OR_GREATER
|
||
internal static double ToDouble(this Int128 number) => (double)number;
|
||
internal static double ToDouble(this UInt128 number) => (double)number;
|
||
|
||
internal static double ToDouble(this Int128? number) => number.HasValue ? (double)number.Value : 0d;
|
||
internal static double ToDouble(this UInt128? number) => number.HasValue ? (double)number.Value : 0d;
|
||
#endif
|
||
|
||
|
||
|
||
// === IEnumerable<T> + yeild ===
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<byte> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<sbyte> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<short> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<ushort> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<int> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<uint> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<nint> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<nuint> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<long> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<ulong> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<Half> numbers)
|
||
{ foreach (var number in numbers) yield return (double)number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<float> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<decimal> numbers)
|
||
{ foreach (var number in numbers) yield return (double)number; }
|
||
|
||
#if NET7_0_OR_GREATER
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<Int128> numbers)
|
||
{ foreach (var number in numbers) yield return (double)number; }
|
||
internal static IEnumerable<double> ToDoubleIterator(this IEnumerable<UInt128> numbers)
|
||
{ foreach (var number in numbers) yield return (double)number; }
|
||
#endif
|
||
|
||
|
||
|
||
|
||
// ========================================================================
|
||
// ГРУППА 1: 32-битные типы (float, int, uint). 1 вектор дает 2 вектора
|
||
// ========================================================================
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<float> source, int len, Span<double> destination)
|
||
{
|
||
ref float srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
|
||
int vectorSize = Vector<float>.Count;
|
||
int doubleVectorSize = Vector<double>.Count;
|
||
int simdEnd = len & ~(vectorSize - 1);
|
||
|
||
for (; i < simdEnd; i += vectorSize)
|
||
{
|
||
var vSrc = Unsafe.As<float, Vector<float>>(ref Unsafe.Add(ref srcRef, i));
|
||
Vector.Widen(vSrc, out var vLow, out var vHigh);
|
||
|
||
Unsafe.As<double, Vector<double>>(ref Unsafe.Add(ref dstRef, i)) = vLow;
|
||
Unsafe.As<double, Vector<double>>(ref Unsafe.Add(ref dstRef, i + doubleVectorSize)) = vHigh;
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<int> source, int len, Span<double> destination)
|
||
{
|
||
ref int srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
|
||
int vectorSize = Vector<int>.Count;
|
||
int doubleVectorSize = Vector<double>.Count;
|
||
int simdEnd = len & ~(vectorSize - 1);
|
||
|
||
for (; i < simdEnd; i += vectorSize)
|
||
{
|
||
var vSrc = Unsafe.As<int, Vector<int>>(ref Unsafe.Add(ref srcRef, i));
|
||
|
||
// Расширяем int (32bit) -> long (64bit), затем конвертируем long -> double
|
||
Vector.Widen(vSrc, out var vLowLong, out var vHighLong);
|
||
|
||
Unsafe.As<double, Vector<double>>(ref Unsafe.Add(ref dstRef, i)) = Vector.ConvertToDouble(vLowLong);
|
||
Unsafe.As<double, Vector<double>>(ref Unsafe.Add(ref dstRef, i + doubleVectorSize)) = Vector.ConvertToDouble(vHighLong);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<uint> source, int len, Span<double> destination)
|
||
{
|
||
ref uint srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
|
||
int vectorSize = Vector<uint>.Count;
|
||
int doubleVectorSize = Vector<double>.Count;
|
||
int simdEnd = len & ~(vectorSize - 1);
|
||
|
||
for (; i < simdEnd; i += vectorSize)
|
||
{
|
||
var vSrc = Unsafe.As<uint, Vector<uint>>(ref Unsafe.Add(ref srcRef, i));
|
||
Vector.Widen(vSrc, out var vLowULong, out var vHighULong);
|
||
|
||
Unsafe.As<double, Vector<double>>(ref Unsafe.Add(ref dstRef, i)) = Vector.ConvertToDouble(vLowULong);
|
||
Unsafe.As<double, Vector<double>>(ref Unsafe.Add(ref dstRef, i + doubleVectorSize)) = Vector.ConvertToDouble(vHighULong);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
|
||
// ========================================================================
|
||
// ГРУППА 2: 64-битные типы (long, ulong). 1 вектор дает 1 вектор
|
||
// ========================================================================
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<long> source, int len, Span<double> destination)
|
||
{
|
||
ref long srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
|
||
int vectorSize = Vector<long>.Count;
|
||
int simdEnd = len & ~(vectorSize - 1);
|
||
|
||
for (; i < simdEnd; i += vectorSize)
|
||
{
|
||
var vSrc = Unsafe.As<long, Vector<long>>(ref Unsafe.Add(ref srcRef, i));
|
||
Unsafe.As<double, Vector<double>>(ref Unsafe.Add(ref dstRef, i)) = Vector.ConvertToDouble(vSrc);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<ulong> source, int len, Span<double> destination)
|
||
{
|
||
ref ulong srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0, vectorSize = Vector<ulong>.Count;
|
||
int simdEnd = len & ~(vectorSize - 1);
|
||
|
||
for (; i < simdEnd; i += vectorSize)
|
||
{
|
||
var vSrc = Unsafe.As<ulong, Vector<ulong>>(ref Unsafe.Add(ref srcRef, i));
|
||
Unsafe.As<double, Vector<double>>(ref Unsafe.Add(ref dstRef, i)) = Vector.ConvertToDouble(vSrc);
|
||
}
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
|
||
// ========================================================================
|
||
// ГРУППА 3: 8 и 16-битные типы (byte, sbyte, short, ushort).
|
||
// Используем Unroll x8 (развернутый цикл), так как это быстрее 3-х каскадов Widen.
|
||
// ========================================================================
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<short> source, int len, Span<double> destination)
|
||
{
|
||
ref short srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~7; // Кратность 8
|
||
|
||
for (; i < unrollEnd; i += 8)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = Unsafe.Add(ref srcRef, i + 3);
|
||
Unsafe.Add(ref dstRef, i + 4) = Unsafe.Add(ref srcRef, i + 4);
|
||
Unsafe.Add(ref dstRef, i + 5) = Unsafe.Add(ref srcRef, i + 5);
|
||
Unsafe.Add(ref dstRef, i + 6) = Unsafe.Add(ref srcRef, i + 6);
|
||
Unsafe.Add(ref dstRef, i + 7) = Unsafe.Add(ref srcRef, i + 7);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<ushort> source, int len, Span<double> destination)
|
||
{
|
||
ref ushort srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~7; // Кратность 8
|
||
|
||
for (; i < unrollEnd; i += 8)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = Unsafe.Add(ref srcRef, i + 3);
|
||
Unsafe.Add(ref dstRef, i + 4) = Unsafe.Add(ref srcRef, i + 4);
|
||
Unsafe.Add(ref dstRef, i + 5) = Unsafe.Add(ref srcRef, i + 5);
|
||
Unsafe.Add(ref dstRef, i + 6) = Unsafe.Add(ref srcRef, i + 6);
|
||
Unsafe.Add(ref dstRef, i + 7) = Unsafe.Add(ref srcRef, i + 7);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<byte> source, int len, Span<double> destination)
|
||
{
|
||
ref byte srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~7; // Кратность 8
|
||
|
||
for (; i < unrollEnd; i += 8)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = Unsafe.Add(ref srcRef, i + 3);
|
||
Unsafe.Add(ref dstRef, i + 4) = Unsafe.Add(ref srcRef, i + 4);
|
||
Unsafe.Add(ref dstRef, i + 5) = Unsafe.Add(ref srcRef, i + 5);
|
||
Unsafe.Add(ref dstRef, i + 6) = Unsafe.Add(ref srcRef, i + 6);
|
||
Unsafe.Add(ref dstRef, i + 7) = Unsafe.Add(ref srcRef, i + 7);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<sbyte> source, int len, Span<double> destination)
|
||
{
|
||
ref sbyte srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~7; // Кратность 8
|
||
|
||
for (; i < unrollEnd; i += 8)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = Unsafe.Add(ref srcRef, i + 3);
|
||
Unsafe.Add(ref dstRef, i + 4) = Unsafe.Add(ref srcRef, i + 4);
|
||
Unsafe.Add(ref dstRef, i + 5) = Unsafe.Add(ref srcRef, i + 5);
|
||
Unsafe.Add(ref dstRef, i + 6) = Unsafe.Add(ref srcRef, i + 6);
|
||
Unsafe.Add(ref dstRef, i + 7) = Unsafe.Add(ref srcRef, i + 7);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<Half> source, int len, Span<double> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
|
||
ref Half srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
|
||
int i = 0;
|
||
int unrollEnd = len & ~7; // Шаг по 8 элементов (8 * 8 байт double = 64 байта строки кэша)
|
||
|
||
// Основной конвейер
|
||
for (; i < unrollEnd; i += 8)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = (double)Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = (double)Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = (double)Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = (double)Unsafe.Add(ref srcRef, i + 3);
|
||
Unsafe.Add(ref dstRef, i + 4) = (double)Unsafe.Add(ref srcRef, i + 4);
|
||
Unsafe.Add(ref dstRef, i + 5) = (double)Unsafe.Add(ref srcRef, i + 5);
|
||
Unsafe.Add(ref dstRef, i + 6) = (double)Unsafe.Add(ref srcRef, i + 6);
|
||
Unsafe.Add(ref dstRef, i + 7) = (double)Unsafe.Add(ref srcRef, i + 7);
|
||
}
|
||
|
||
// Остаток цикла
|
||
for (; i < len; i++)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = (double)Unsafe.Add(ref srcRef, i);
|
||
}
|
||
}
|
||
|
||
|
||
// ========================================================================
|
||
// ГРУППА 4: Типы без SIMD и новые типы .NET 7 (decimal, nint, Int128, UInt128).
|
||
// Используем Unroll x4 (структуры тяжелые, х8 замусорит кэш инструкций).
|
||
// ========================================================================
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<decimal> source, int len, Span<double> destination)
|
||
{
|
||
ref decimal srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~3;
|
||
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = (double)Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = (double)Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = (double)Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = (double)Unsafe.Add(ref srcRef, i + 3);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = (double)Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
#if NET7_0_OR_GREATER
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<Int128> source, int len, Span<double> destination)
|
||
{
|
||
ref Int128 srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~3;
|
||
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = (double)Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = (double)Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = (double)Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = (double)Unsafe.Add(ref srcRef, i + 3);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = (double)Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<UInt128> source, int len, Span<double> destination)
|
||
{
|
||
ref UInt128 srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~3;
|
||
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = (double)Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = (double)Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = (double)Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = (double)Unsafe.Add(ref srcRef, i + 3);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = (double)Unsafe.Add(ref srcRef, i);
|
||
}
|
||
#endif
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<nint> source, int len, Span<double> destination)
|
||
{
|
||
ref nint srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~3;
|
||
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = Unsafe.Add(ref srcRef, i + 3);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<nuint> source, int len, Span<double> destination)
|
||
{
|
||
ref nuint srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0;
|
||
int unrollEnd = len & ~3;
|
||
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
Unsafe.Add(ref dstRef, i + 1) = Unsafe.Add(ref srcRef, i + 1);
|
||
Unsafe.Add(ref dstRef, i + 2) = Unsafe.Add(ref srcRef, i + 2);
|
||
Unsafe.Add(ref dstRef, i + 3) = Unsafe.Add(ref srcRef, i + 3);
|
||
}
|
||
|
||
for (; i < len; i++) Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<byte> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this byte[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<byte> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<byte> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is byte[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<byte> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<byte> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is byte[] array) return array.ToDouble();
|
||
if (numbers is List<byte> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<byte> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<sbyte> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this sbyte[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<sbyte> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<sbyte> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is sbyte[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<sbyte> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<sbyte> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is sbyte[] array) return array.ToDouble();
|
||
if (numbers is List<sbyte> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<sbyte> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<short> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this short[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<short> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<short> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is short[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<short> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<short> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is short[] array) return array.ToDouble();
|
||
if (numbers is List<short> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<short> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<ushort> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this ushort[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<ushort> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<ushort> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is ushort[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<ushort> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<ushort> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is ushort[] array) return array.ToDouble();
|
||
if (numbers is List<ushort> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<ushort> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<int> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this int[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<int> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<int> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is int[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<int> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<int> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is int[] array) return array.ToDouble();
|
||
if (numbers is List<int> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<int> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<uint> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this uint[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<uint> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<uint> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is uint[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<uint> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<uint> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is uint[] array) return array.ToDouble();
|
||
if (numbers is List<uint> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<uint> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<nint> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this nint[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<nint> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<nint> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is nint[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<nint> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<nint> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is nint[] array) return array.ToDouble();
|
||
if (numbers is List<nint> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<nint> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<nuint> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this nuint[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<nuint> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<nuint> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is nuint[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<nuint> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<nuint> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is nuint[] array) return array.ToDouble();
|
||
if (numbers is List<nuint> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<nuint> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<long> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this long[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<long> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<long> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is long[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<long> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<long> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is long[] array) return array.ToDouble();
|
||
if (numbers is List<long> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<long> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<ulong> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this ulong[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<ulong> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<ulong> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is ulong[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<ulong> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<ulong> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is ulong[] array) return array.ToDouble();
|
||
if (numbers is List<ulong> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<ulong> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<Half> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this Half[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<Half> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<Half> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is Half[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<Half> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<Half> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is Half[] array) return array.ToDouble();
|
||
if (numbers is List<Half> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<Half> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<float> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this float[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<float> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<float> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is float[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<float> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<float> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is float[] array) return array.ToDouble();
|
||
if (numbers is List<float> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<float> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<decimal> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this decimal[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<decimal> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<decimal> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is decimal[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<decimal> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<decimal> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is decimal[] array) return array.ToDouble();
|
||
if (numbers is List<decimal> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<decimal> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
#if NET7_0_OR_GREATER
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<Int128> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this Int128[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<Int128> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<Int128> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is Int128[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<Int128> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<Int128> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is Int128[] array) return array.ToDouble();
|
||
if (numbers is List<Int128> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<Int128> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double[] ToDouble(this IEnumerable<UInt128> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double[] destination = new double[count];
|
||
ref double dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double[] ToDouble(this UInt128[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double> ToDouble(this List<UInt128> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<UInt128> numbers, Span<double> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is UInt128[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<UInt128> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double> ToDouble(this IEnumerable<UInt128> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is UInt128[] array) return array.ToDouble();
|
||
if (numbers is List<UInt128> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<UInt128> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
// === IEnumerable<T> + yeild ===
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<byte?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<sbyte?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<short?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<ushort?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<int?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<uint?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<nint?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<nuint?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<long?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<ulong?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<Half?> numbers)
|
||
{ foreach (var number in numbers) yield return (double?)number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<float?> numbers)
|
||
{ foreach (var number in numbers) yield return number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<decimal?> numbers)
|
||
{ foreach (var number in numbers) yield return (double?)number; }
|
||
|
||
#if NET7_0_OR_GREATER
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<Int128?> numbers)
|
||
{ foreach (var number in numbers) yield return (double?)number; }
|
||
internal static IEnumerable<double?> ToDoubleIterator(this IEnumerable<UInt128?> numbers)
|
||
{ foreach (var number in numbers) yield return (double?)number; }
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<byte?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref byte? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<sbyte?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref sbyte? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<short?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref short? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<ushort?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref ushort? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<int?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref int? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<uint?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref uint? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<nint?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref nint? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<nuint?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref nuint? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<long?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref long? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<ulong?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref ulong? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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.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.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<Half?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref Half? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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?)(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?)(double)u.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<float?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref float? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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?)(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?)(double)u.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<decimal?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref decimal? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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?)(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?)(double)u.Value : null; }
|
||
}
|
||
|
||
#if NET7_0_OR_GREATER
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<Int128?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref Int128? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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?)(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?)(double)u.Value : null; }
|
||
}
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
internal static void ToDoubleCore(this ReadOnlySpan<UInt128?> source, int len, Span<double?> destination)
|
||
{
|
||
if (len <= 0) return;
|
||
ref UInt128? srcRef = ref MemoryMarshal.GetReference(source);
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
int i = 0; int unrollEnd = len & ~3;
|
||
for (; i < unrollEnd; i += 4)
|
||
{
|
||
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?)(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?)(double)u.Value : null; }
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<byte?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this byte?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<byte?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<byte?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is byte?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<byte?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<byte?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is byte?[] array) return array.ToDouble();
|
||
if (numbers is List<byte?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<byte?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<sbyte?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this sbyte?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<sbyte?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<sbyte?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is sbyte?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<sbyte?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<sbyte?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is sbyte?[] array) return array.ToDouble();
|
||
if (numbers is List<sbyte?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<sbyte?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<short?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this short?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<short?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<short?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is short?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<short?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<short?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is short?[] array) return array.ToDouble();
|
||
if (numbers is List<short?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<short?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<ushort?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this ushort?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<ushort?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<ushort?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is ushort?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<ushort?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<ushort?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is ushort?[] array) return array.ToDouble();
|
||
if (numbers is List<ushort?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<ushort?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<int?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this int?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<int?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<int?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is int?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<int?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<int?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is int?[] array) return array.ToDouble();
|
||
if (numbers is List<int?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<int?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<uint?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this uint?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<uint?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<uint?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is uint?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<uint?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<uint?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is uint?[] array) return array.ToDouble();
|
||
if (numbers is List<uint?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<uint?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<nint?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this nint?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<nint?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<nint?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is nint?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<nint?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<nint?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is nint?[] array) return array.ToDouble();
|
||
if (numbers is List<nint?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<nint?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<nuint?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this nuint?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<nuint?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<nuint?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is nuint?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<nuint?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<nuint?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is nuint?[] array) return array.ToDouble();
|
||
if (numbers is List<nuint?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<nuint?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<long?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this long?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<long?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<long?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is long?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<long?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<long?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is long?[] array) return array.ToDouble();
|
||
if (numbers is List<long?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<long?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<ulong?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this ulong?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<ulong?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<ulong?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is ulong?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<ulong?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<ulong?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is ulong?[] array) return array.ToDouble();
|
||
if (numbers is List<ulong?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<ulong?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<Half?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this Half?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<Half?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<Half?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is Half?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<Half?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<Half?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is Half?[] array) return array.ToDouble();
|
||
if (numbers is List<Half?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<Half?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<float?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this float?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<float?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<float?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is float?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<float?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<float?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is float?[] array) return array.ToDouble();
|
||
if (numbers is List<float?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<float?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<decimal?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this decimal?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<decimal?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<decimal?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is decimal?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<decimal?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<decimal?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is decimal?[] array) return array.ToDouble();
|
||
if (numbers is List<decimal?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<decimal?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
#if NET7_0_OR_GREATER
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<Int128?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this Int128?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<Int128?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<Int128?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is Int128?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<Int128?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<Int128?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is Int128?[] array) return array.ToDouble();
|
||
if (numbers is List<Int128?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<Int128?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
|
||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
private static double?[] ToDouble(this IEnumerable<UInt128?> source, int count)
|
||
{
|
||
if (count == 0) return [];
|
||
int i = 0;
|
||
double?[] destination = new double?[count];
|
||
ref double? dstRef = ref MemoryMarshal.GetArrayDataReference(destination);
|
||
foreach (var item in source)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
return destination;
|
||
}
|
||
internal static double?[] ToDouble(this UInt128?[] numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Length;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
numbers.ToDoubleCore(len, result);
|
||
return result;
|
||
}
|
||
internal static List<double?> ToDouble(this List<UInt128?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
int len = numbers.Count;
|
||
if (len == 0) return [];
|
||
|
||
var result = new double?[len];
|
||
CollectionsMarshal.AsSpan(numbers).ToDoubleCore(len, result);
|
||
return result.WrapAsList();
|
||
}
|
||
internal static void ToDouble(this IReadOnlyCollection<UInt128?> numbers, Span<double?> destination)
|
||
{
|
||
if (numbers is null) return;
|
||
int count = numbers.Count;
|
||
if (count == 0) return;
|
||
if (destination.Length < count)
|
||
throw new ArgumentException("Destination too short");
|
||
|
||
if (numbers is UInt128?[] array) { array.ToDoubleCore(count, destination); return; }
|
||
if (numbers is List<UInt128?> list) { CollectionsMarshal.AsSpan(list).ToDoubleCore(count, destination); return; }
|
||
|
||
int i = 0;
|
||
ref double? dstRef = ref MemoryMarshal.GetReference(destination);
|
||
foreach (var item in numbers)
|
||
{
|
||
if ((uint)i >= (uint)count) break;
|
||
Unsafe.Add(ref dstRef, i++) = (double?)item;
|
||
}
|
||
}
|
||
internal static IEnumerable<double?> ToDouble(this IEnumerable<UInt128?> numbers)
|
||
{
|
||
if (numbers is null) return null!;
|
||
if (numbers is UInt128?[] array) return array.ToDouble();
|
||
if (numbers is List<UInt128?> list) return list.ToDouble();
|
||
if (numbers is IReadOnlyCollection<UInt128?> roc) return roc.ToDouble(roc.Count);
|
||
return numbers.ToDoubleIterator();
|
||
}
|
||
#endif
|
||
} |