This commit is contained in:
2026-06-01 01:31:31 +07:00
parent ba77411c4a
commit e43c885fbe
7 changed files with 5146 additions and 2238 deletions

View File

@@ -87,12 +87,12 @@ namespace QWERTYkez.Mensura
string ns = info.Namespace;
// Здесь должен быть полный код из вашего файла XXXXXXXXXXXX.cs
// с заменой XXXXXXXXXXXXXX на {typeName}. Для краткости приведён скелет.
// с заменой {typeName} на {typeName}. Для краткости приведён скелет.
// Вы должны скопировать сюда всё содержимое вашего второго файла,
// заменив XXXXXXXXXXXXXX на {typeName}.
// заменив {typeName} на {typeName}.
string skeleton = @"
global using {typeName} = QWERTYkez.Mensura.Units.{typeName};
global using {typeName}Extensions = QWERTYkez.Mensura.Units.{typeName}Extensions;
global using {typeName}Extensions = QWERTYkez.Mensura.Units.{typeName}Extension;
global using {typeName}Converter = QWERTYkez.Mensura.Units.{typeName}Converter;
using System.Globalization;
@@ -118,13 +118,8 @@ public readonly partial record struct {typeName} : IMensuraUnit<{typeName}>, IEq
[JsonIgnore, IgnoreDataMember] public bool IsPositive => _Value >= 0;
[JsonIgnore, IgnoreDataMember] public bool IsGreaterThanZero => _Value > 0;
[JsonIgnore, IgnoreDataMember] public bool IsNegative => double.IsNegative(_Value);
[JsonIgnore, IgnoreDataMember] public bool IsNegative => _Value < 0;
[JsonIgnore, IgnoreDataMember] public bool IsZero => _Value == 0;
[JsonIgnore, IgnoreDataMember] public bool IsNaN => double.IsNaN(_Value);
[JsonIgnore, IgnoreDataMember] public bool IsFinite => double.IsFinite(_Value);
[JsonIgnore, IgnoreDataMember] public bool IsInfinity => double.IsInfinity(_Value);
[JsonIgnore, IgnoreDataMember] public bool IsPositiveInfinity => double.IsPositiveInfinity(_Value);
[JsonIgnore, IgnoreDataMember] public bool IsNegativeInfinity => double.IsNegativeInfinity(_Value);
public static {typeName} Zero { get; } = new(0d);
@@ -308,19 +303,19 @@ public readonly partial record struct {typeName} : IMensuraUnit<{typeName}>, IEq
}
}
public static class {typeName}Extensions
public static class {typeName}Extension
{
internal static double ToDouble(this {typeName}? unit) => unit is null ? 0d : unit.Value._Value;
public static {typeName} MetricSum(this IEnumerable<{typeName}> units) => new() { Value = units?.Sum(m => m._Value) ?? 0d };
public static {typeName} MetricAverage(this IEnumerable<{typeName}> units) => new() { Value = units?.Average(m => m._Value) ?? double.NaN };
public static {typeName} MetricMax(this IEnumerable<{typeName}> units) => new() { Value = units?.Max(m => m._Value) ?? double.MinValue };
public static {typeName} MetricMin(this IEnumerable<{typeName}> units) => new() { Value = units?.Min(m => m._Value) ?? double.MaxValue };
public static {typeName} MetricSum(this IEnumerable<{typeName}> units) => new(units?.Sum(m => m._Value) ?? 0d);
public static {typeName} MetricAverage(this IEnumerable<{typeName}> units) => new(units?.Average(m => m._Value) ?? double.NaN);
public static {typeName} MetricMax(this IEnumerable<{typeName}> units) => new(units?.Max(m => m._Value) ?? double.MinValue);
public static {typeName} MetricMin(this IEnumerable<{typeName}> units) => new(units?.Min(m => m._Value) ?? double.MaxValue);
public static {typeName} MetricSum(this IEnumerable<{typeName}?> units) => new() { Value = units?.Sum(m => m.ToDouble()) ?? 0d };
public static {typeName} MetricAverage(this IEnumerable<{typeName}?> units) => new() { Value = units?.Average(m => m.ToDouble()) ?? double.NaN };
public static {typeName} MetricMax(this IEnumerable<{typeName}?> units) => new() { Value = units?.Max(m => m.ToDouble()) ?? double.MinValue };
public static {typeName} MetricMin(this IEnumerable<{typeName}?> units) => new() { Value = units?.Min(m => m.ToDouble()) ?? double.MaxValue };
public static {typeName} MetricSum(this IEnumerable<{typeName}?> units) => new(units?.Sum(m => m.ToDouble()) ?? 0d);
public static {typeName} MetricAverage(this IEnumerable<{typeName}?> units) => new(units?.Average(m => m.ToDouble()) ?? double.NaN);
public static {typeName} MetricMax(this IEnumerable<{typeName}?> units) => new(units?.Max(m => m.ToDouble()) ?? double.MinValue);
public static {typeName} MetricMin(this IEnumerable<{typeName}?> units) => new(units?.Min(m => m.ToDouble()) ?? double.MaxValue);
internal static void MultiplyCore(ReadOnlySpan<{typeName}> source, double value, Span<{typeName}> destination)
@@ -329,7 +324,7 @@ public static class {typeName}Extensions
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
var vectorizedValue = new Vector<double>(value);
var vectorized_Value = new Vector<double>(value);
int vectorSize = Vector<double>.Count;
int i = 0;
@@ -342,7 +337,7 @@ public static class {typeName}Extensions
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
var vector = new Vector<double>(srcWindow);
var multiplied = vector * vectorizedValue;
var multiplied = vector * vectorized_Value;
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
multiplied.CopyTo(dstWindow);
@@ -363,7 +358,7 @@ public static class {typeName}Extensions
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
var vectorizedValue = new Vector<double>(divisor);
var vectorized_Value = new Vector<double>(divisor);
int vectorSize = Vector<double>.Count;
int i = 0;
@@ -376,7 +371,7 @@ public static class {typeName}Extensions
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
var vector = new Vector<double>(srcWindow);
var multiplied = vector / vectorizedValue;
var multiplied = vector / vectorized_Value;
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
multiplied.CopyTo(dstWindow);
@@ -393,7 +388,7 @@ public static class {typeName}Extensions
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
var vectorizedValue = new Vector<double>(dividend);
var vectorized_Value = new Vector<double>(dividend);
var zeroVector = Vector<double>.Zero; // Вектор из нулей для сравнения
int vectorSize = Vector<double>.Count;
int i = 0;
@@ -414,7 +409,7 @@ public static class {typeName}Extensions
throw new DivideByZeroException($""Обнаружен делитель, равный нулю, в районе индексов {i}..{i + vectorSize - 1}."");
}
var multiplied = vectorizedValue / vector;
var multiplied = vectorized_Value / vector;
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
multiplied.CopyTo(dstWindow);
@@ -437,7 +432,7 @@ public static class {typeName}Extensions
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
var vectorizedValue = new Vector<double>(summand);
var vectorized_Value = new Vector<double>(summand);
int vectorSize = Vector<double>.Count;
int i = 0;
@@ -450,7 +445,7 @@ public static class {typeName}Extensions
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
var vector = new Vector<double>(srcWindow);
var multiplied = vector + vectorizedValue;
var multiplied = vector + vectorized_Value;
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
multiplied.CopyTo(dstWindow);
@@ -467,7 +462,7 @@ public static class {typeName}Extensions
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
var vectorizedValue = new Vector<double>(subtrahend);
var vectorized_Value = new Vector<double>(subtrahend);
int vectorSize = Vector<double>.Count;
int i = 0;
@@ -480,7 +475,7 @@ public static class {typeName}Extensions
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
var vector = new Vector<double>(srcWindow);
var multiplied = vector - vectorizedValue;
var multiplied = vector - vectorized_Value;
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
multiplied.CopyTo(dstWindow);
@@ -497,7 +492,7 @@ public static class {typeName}Extensions
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
var vectorizedValue = new Vector<double>(minuend);
var vectorized_Value = new Vector<double>(minuend);
int vectorSize = Vector<double>.Count;
int i = 0;
@@ -510,7 +505,7 @@ public static class {typeName}Extensions
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
var vector = new Vector<double>(srcWindow);
var multiplied = vectorizedValue - vector;
var multiplied = vectorized_Value - vector;
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
multiplied.CopyTo(dstWindow);
@@ -550,7 +545,7 @@ public static class {typeName}Extensions
if (exp < 0)
{
baseVector = Vector<double>.One / baseVector;
exp = -exp; // Внимание: может переполниться при int.MinValue, но для степеней это редчайший кейс
exp = -exp; // Внимание: может переполниться при int.Min_Value, но для степеней это редчайший кейс
}
var result = Vector<double>.One;
@@ -731,7 +726,7 @@ public static class {typeName}Extensions
public static Tcoll Multiply<Tcoll>(this ICollection<{typeName}> units, double multiplicator)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -744,7 +739,7 @@ public static class {typeName}Extensions
public static Tcoll Multiply<Tcoll>(this ICollection<{typeName}?> units, double multiplicator)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -936,7 +931,7 @@ public static class {typeName}Extensions
public static Tcoll Divide<Tcoll>(this ICollection<{typeName}> units, double divisor)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -947,7 +942,7 @@ public static class {typeName}Extensions
public static Tcoll Divide<Tcoll>(this double dividend, ICollection<{typeName}> units)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -958,7 +953,7 @@ public static class {typeName}Extensions
public static Tcoll Divide<Tcoll>(this ICollection<{typeName}?> units, double divisor)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -969,7 +964,7 @@ public static class {typeName}Extensions
public static Tcoll Divide<Tcoll>(this double dividend, ICollection<{typeName}?> units)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1101,7 +1096,7 @@ public static class {typeName}Extensions
public static Tcoll Plus<Tcoll>(this ICollection<{typeName}> units, double summand)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1114,7 +1109,7 @@ public static class {typeName}Extensions
public static Tcoll Plus<Tcoll>(this ICollection<{typeName}?> units, double summand)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1297,7 +1292,7 @@ public static class {typeName}Extensions
public static Tcoll Minus<Tcoll>(this ICollection<{typeName}> units, double subtrahend)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1308,7 +1303,7 @@ public static class {typeName}Extensions
public static Tcoll Minus<Tcoll>(this double minuend, ICollection<{typeName}> units)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1319,7 +1314,7 @@ public static class {typeName}Extensions
public static Tcoll Minus<Tcoll>(this ICollection<{typeName}?> units, double subtrahend)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1330,7 +1325,7 @@ public static class {typeName}Extensions
public static Tcoll Minus<Tcoll>(this double minuend, ICollection<{typeName}?> units)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1453,7 +1448,7 @@ public static class {typeName}Extensions
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units, int power)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1464,7 +1459,7 @@ public static class {typeName}Extensions
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units, int power)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1573,7 +1568,7 @@ public static class {typeName}Extensions
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units, double power)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1584,7 +1579,7 @@ public static class {typeName}Extensions
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units, double power)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1694,7 +1689,7 @@ public static class {typeName}Extensions
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units)
where Tcoll : class, ICollection<{typeName}>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1705,7 +1700,7 @@ public static class {typeName}Extensions
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units)
where Tcoll : class, ICollection<{typeName}?>, new()
{
ArgumentNullException.ThrowIfNull(units);
if (units is null) return null!;
var tColl = new Tcoll();
if (tColl is List<{typeName}> list)
list.Capacity = units.Count;
@@ -1737,12 +1732,12 @@ public class {typeName}Converter : JsonConverter<{typeName}>
public override {typeName} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
double doubleValue;
double double_Value;
if (reader.TokenType == JsonTokenType.String)
{
// Безопасно парсим double из строки с поддержкой точки как разделителя
if (!double.TryParse(reader.GetString(), NumberStyles.Float, Culture, out doubleValue))
if (!double.TryParse(reader.GetString(), NumberStyles.Float, Culture, out double_Value))
{
throw new JsonException($""Не удалось преобразовать строковое значение в double для метрики {nameof({typeName})}."");
}
@@ -1750,10 +1745,10 @@ public class {typeName}Converter : JsonConverter<{typeName}>
else
{
// Прямое быстрое чтение числа из JSON
doubleValue = reader.GetDouble();
double_Value = reader.GetDouble();
}
return new(doubleValue);
return new(double_Value);
}
public override void Write(Utf8JsonWriter writer, {typeName} value, JsonSerializerOptions options)
@@ -1774,12 +1769,12 @@ public class {typeName}Converter : JsonConverter<{typeName}>
{
string propertyName = reader.GetString()!;
if (!double.TryParse(propertyName, NumberStyles.Float, Culture, out double doubleValue))
if (!double.TryParse(propertyName, NumberStyles.Float, Culture, out double double_Value))
{
throw new JsonException($""Невалидное числовое значение в ключе свойства JSON: '{propertyName}' для метрики {nameof({typeName})}."");
}
return new(doubleValue);
return new(double_Value);
}
}
";