Files
QWERTYkez.Mensura/QWERTYkez.Mensura/Extensions/DoubleExtensions.cs
2026-06-12 23:34:00 +07:00

2660 lines
108 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}