+++
This commit is contained in:
@@ -1,226 +1,226 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
//using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
//using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using Microsoft.CodeAnalysis.Text;
|
//using Microsoft.CodeAnalysis.Text;
|
||||||
using System.Collections.Generic;
|
//using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
//using System.Collections.Immutable;
|
||||||
using System.Linq;
|
//using System.Linq;
|
||||||
using System.Text;
|
//using System.Text;
|
||||||
|
|
||||||
namespace QWERTYkez.Mensura.Generator;
|
//namespace QWERTYkez.Mensura.Generator;
|
||||||
|
|
||||||
[Generator(LanguageNames.CSharp)]
|
//[Generator(LanguageNames.CSharp)]
|
||||||
internal class CollectionsOperatorsGenerator : IIncrementalGenerator
|
//internal class CollectionsOperatorsGenerator : IIncrementalGenerator
|
||||||
{
|
//{
|
||||||
private const string AttributeShortName = "CollectionsOperatorsGenerator";
|
// private const string AttributeShortName = "CollectionsOperatorsGenerator";
|
||||||
private const string AttributeFullName = AttributeShortName + "Attribute";
|
// private const string AttributeFullName = AttributeShortName + "Attribute";
|
||||||
|
|
||||||
private const string AttributeSource = @"namespace QWERTYkez.Mensura;
|
// private const string AttributeSource = @"namespace QWERTYkez.Mensura;
|
||||||
|
|
||||||
[System.AttributeUsage(System.AttributeTargets.Struct | System.AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
//[System.AttributeUsage(System.AttributeTargets.Struct | System.AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||||
internal sealed class CollectionsOperatorsGeneratorAttribute : System.Attribute { }";
|
//internal sealed class CollectionsOperatorsGeneratorAttribute : System.Attribute { }";
|
||||||
|
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
// public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||||
{
|
// {
|
||||||
context.RegisterPostInitializationOutput(context =>
|
// context.RegisterPostInitializationOutput(context =>
|
||||||
context.AddSource(
|
// context.AddSource(
|
||||||
$"{AttributeFullName}.g",
|
// $"{AttributeFullName}.g",
|
||||||
SourceText.From(AttributeSource, Encoding.UTF8)));
|
// SourceText.From(AttributeSource, Encoding.UTF8)));
|
||||||
|
|
||||||
var operatorsPipeline =
|
// var operatorsPipeline =
|
||||||
context.SyntaxProvider.CreateSyntaxProvider<KeyValuePair<ClassData, ImmutableArray<Operation>>>(
|
// context.SyntaxProvider.CreateSyntaxProvider<KeyValuePair<ClassData, ImmutableArray<Operation>>>(
|
||||||
(node, _) =>
|
// (node, _) =>
|
||||||
{
|
// {
|
||||||
if (node is ClassDeclarationSyntax cds)
|
// if (node is ClassDeclarationSyntax cds)
|
||||||
{
|
// {
|
||||||
SyntaxNode sn = cds;
|
// SyntaxNode sn = cds;
|
||||||
while (sn.Parent is not null &&
|
// while (sn.Parent is not null &&
|
||||||
sn.Parent is not FileScopedNamespaceDeclarationSyntax)
|
// sn.Parent is not FileScopedNamespaceDeclarationSyntax)
|
||||||
{
|
// {
|
||||||
sn = sn.Parent;
|
// sn = sn.Parent;
|
||||||
}
|
// }
|
||||||
if (sn.Parent is FileScopedNamespaceDeclarationSyntax
|
// if (sn.Parent is FileScopedNamespaceDeclarationSyntax
|
||||||
&& cds.TypeParameterList is null
|
// && cds.TypeParameterList is null
|
||||||
&&
|
// &&
|
||||||
((cds.Members.OfType<OperatorDeclarationSyntax>()
|
// ((cds.Members.OfType<OperatorDeclarationSyntax>()
|
||||||
.Where(m => m.AttributeLists.SelectMany(al => al.Attributes)
|
// .Where(m => m.AttributeLists.SelectMany(al => al.Attributes)
|
||||||
.Any(a => a.Name.GetText().ToString().Contains(AttributeShortName)))
|
// .Any(a => a.Name.GetText().ToString().Contains(AttributeShortName)))
|
||||||
.Any())
|
// .Any())
|
||||||
||
|
// ||
|
||||||
(cds.Modifiers.Any(m => m.Text == "partial")
|
// (cds.Modifiers.Any(m => m.Text == "partial")
|
||||||
&& cds.AttributeLists
|
// && cds.AttributeLists
|
||||||
.SelectMany(al => al.Attributes)
|
// .SelectMany(al => al.Attributes)
|
||||||
.Any(a => a.Name
|
// .Any(a => a.Name
|
||||||
.GetText()
|
// .GetText()
|
||||||
.ToString()
|
// .ToString()
|
||||||
.Contains(AttributeShortName)))))
|
// .Contains(AttributeShortName)))))
|
||||||
{
|
// {
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return false;
|
// return false;
|
||||||
},
|
// },
|
||||||
(syntax, _) =>
|
// (syntax, _) =>
|
||||||
{
|
// {
|
||||||
string nameSpace;
|
// string nameSpace;
|
||||||
var cds = (ClassDeclarationSyntax)syntax.Node;
|
// var cds = (ClassDeclarationSyntax)syntax.Node;
|
||||||
{
|
// {
|
||||||
SyntaxNode sn = cds;
|
// SyntaxNode sn = cds;
|
||||||
while (sn.Parent is not FileScopedNamespaceDeclarationSyntax)
|
// while (sn.Parent is not FileScopedNamespaceDeclarationSyntax)
|
||||||
{
|
// {
|
||||||
sn = sn.Parent!;
|
// sn = sn.Parent!;
|
||||||
}
|
// }
|
||||||
var nds = (FileScopedNamespaceDeclarationSyntax)sn.Parent;
|
// var nds = (FileScopedNamespaceDeclarationSyntax)sn.Parent;
|
||||||
nameSpace = nds.Name.ToString();
|
// nameSpace = nds.Name.ToString();
|
||||||
}
|
// }
|
||||||
var Res = new StringBuilder();
|
// var Res = new StringBuilder();
|
||||||
{
|
// {
|
||||||
Res.Append(cds.Modifiers);
|
// Res.Append(cds.Modifiers);
|
||||||
Res.Append(" class ");
|
// Res.Append(" class ");
|
||||||
Res.Append(cds.Identifier.Text);
|
// Res.Append(cds.Identifier.Text);
|
||||||
Res.Append(" ");
|
// Res.Append(" ");
|
||||||
Res.Append(cds.BaseList);
|
// Res.Append(cds.BaseList);
|
||||||
Res.Append(" ");
|
// Res.Append(" ");
|
||||||
Res.Append(cds.ConstraintClauses);
|
// Res.Append(cds.ConstraintClauses);
|
||||||
}
|
// }
|
||||||
|
|
||||||
var operators = cds.Members.OfType<OperatorDeclarationSyntax>()
|
// var operators = cds.Members.OfType<OperatorDeclarationSyntax>()
|
||||||
.Where(m => m.AttributeLists
|
// .Where(m => m.AttributeLists
|
||||||
.SelectMany(al => al.Attributes)
|
// .SelectMany(al => al.Attributes)
|
||||||
.Any(a => a.Name.GetText().ToString().Contains(AttributeShortName)))
|
// .Any(a => a.Name.GetText().ToString().Contains(AttributeShortName)))
|
||||||
.Where(mb => mb.ParameterList.Parameters.Count == 2)
|
// .Where(mb => mb.ParameterList.Parameters.Count == 2)
|
||||||
.Select(mb => new Operation()
|
// .Select(mb => new Operation()
|
||||||
{
|
// {
|
||||||
ReturnType = mb.ReturnType.ToString(),
|
// ReturnType = mb.ReturnType.ToString(),
|
||||||
OperatorToken = mb.OperatorToken.Text,
|
// OperatorToken = mb.OperatorToken.Text,
|
||||||
TypeA = mb.ParameterList.Parameters[0].Type!.ToString(),
|
// TypeA = mb.ParameterList.Parameters[0].Type!.ToString(),
|
||||||
TypeB = mb.ParameterList.Parameters[1].Type!.ToString(),
|
// TypeB = mb.ParameterList.Parameters[1].Type!.ToString(),
|
||||||
});
|
// });
|
||||||
return new(new(nameSpace, cds.Identifier.Text, Res.ToString()), [.. operators]);
|
// return new(new(nameSpace, cds.Identifier.Text, Res.ToString()), [.. operators]);
|
||||||
})
|
// })
|
||||||
.Collect();
|
// .Collect();
|
||||||
|
|
||||||
context.RegisterSourceOutput(operatorsPipeline, GenerateOperators);
|
// context.RegisterSourceOutput(operatorsPipeline, GenerateOperators);
|
||||||
}
|
// }
|
||||||
|
|
||||||
readonly static string[] CollectionTypes = ["MetricArray", "MetricList", "MetricObservableCollection"];
|
// readonly static string[] CollectionTypes = ["MetricArray", "MetricList", "MetricObservableCollection"];
|
||||||
static void GenerateOperators(SourceProductionContext context, ImmutableArray<KeyValuePair<ClassData, ImmutableArray<Operation>>> pairs)
|
// static void GenerateOperators(SourceProductionContext context, ImmutableArray<KeyValuePair<ClassData, ImmutableArray<Operation>>> pairs)
|
||||||
{
|
// {
|
||||||
foreach (var ng in pairs.GroupBy(c => c.Key.NameSpace))
|
// foreach (var ng in pairs.GroupBy(c => c.Key.NameSpace))
|
||||||
{
|
// {
|
||||||
StringBuilder document = new("namespace ");
|
// StringBuilder document = new("namespace ");
|
||||||
document.Append(ng.Key);
|
// document.Append(ng.Key);
|
||||||
document.Append(";");
|
// document.Append(";");
|
||||||
|
|
||||||
var classes = ng.ToList().Select(c => (ClassData?)c.Key).ToList();
|
// var classes = ng.ToList().Select(c => (ClassData?)c.Key).ToList();
|
||||||
var operations = ng.ToList().SelectMany(c => c.Value).ToList();
|
// var operations = ng.ToList().SelectMany(c => c.Value).ToList();
|
||||||
var multiplications = operations.Where(op => op.OperatorToken == "*").ToList();
|
// var multiplications = operations.Where(op => op.OperatorToken == "*").ToList();
|
||||||
var divisions = operations.Where(op => op.OperatorToken == "/").ToList();
|
// var divisions = operations.Where(op => op.OperatorToken == "/").ToList();
|
||||||
|
|
||||||
foreach (var ops in multiplications.GroupBy(op => op.TypeA))
|
// foreach (var ops in multiplications.GroupBy(op => op.TypeA))
|
||||||
{
|
// {
|
||||||
var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key);
|
// var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key);
|
||||||
if (Class is not null)
|
// if (Class is not null)
|
||||||
{
|
// {
|
||||||
document.AppendLine();
|
// document.AppendLine();
|
||||||
document.AppendLine();
|
// document.AppendLine();
|
||||||
document.AppendLine(Class.Value.ClassHeader);
|
// document.AppendLine(Class.Value.ClassHeader);
|
||||||
document.AppendLine("{");
|
// document.AppendLine("{");
|
||||||
foreach (var op in ops)
|
// foreach (var op in ops)
|
||||||
foreach (var ct in CollectionTypes)
|
// foreach (var ct in CollectionTypes)
|
||||||
{
|
// {
|
||||||
document.AppendLine(@$"
|
// document.AppendLine(@$"
|
||||||
public static {ct}<{op.ReturnType}> operator *({op.TypeA} left, {ct}<{op.TypeB}> right) => right.MetricSelect(UU => left * UU);
|
// public static {ct}<{op.ReturnType}> operator *({op.TypeA} left, {ct}<{op.TypeB}> right) => right.MetricSelect(UU => left * UU);
|
||||||
public static {ct}<{op.ReturnType}> operator *({ct}<{op.TypeB}> left, {op.TypeA} right) => left.MetricSelect(UU => UU * right);
|
// public static {ct}<{op.ReturnType}> operator *({ct}<{op.TypeB}> left, {op.TypeA} right) => left.MetricSelect(UU => UU * right);
|
||||||
");
|
//");
|
||||||
}
|
// }
|
||||||
document.Append("}");
|
// document.Append("}");
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
context.ReportDiagnostic(Diagnostic.Create(new(
|
// context.ReportDiagnostic(Diagnostic.Create(new(
|
||||||
"MSG0001",
|
// "MSG0001",
|
||||||
"Need a class with an attribute",
|
// "Need a class with an attribute",
|
||||||
$"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"",
|
// $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"",
|
||||||
"category",
|
// "category",
|
||||||
DiagnosticSeverity.Error,
|
// DiagnosticSeverity.Error,
|
||||||
true), null, ops.Key));
|
// true), null, ops.Key));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
foreach (var ops in divisions.GroupBy(op => op.TypeA))
|
// foreach (var ops in divisions.GroupBy(op => op.TypeA))
|
||||||
{
|
// {
|
||||||
var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key);
|
// var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key);
|
||||||
if (Class is not null)
|
// if (Class is not null)
|
||||||
{
|
// {
|
||||||
document.AppendLine();
|
// document.AppendLine();
|
||||||
document.AppendLine();
|
// document.AppendLine();
|
||||||
document.AppendLine(Class.Value.ClassHeader);
|
// document.AppendLine(Class.Value.ClassHeader);
|
||||||
document.AppendLine("{");
|
// document.AppendLine("{");
|
||||||
foreach (var op in ops)
|
// foreach (var op in ops)
|
||||||
foreach (var ct in CollectionTypes)
|
// foreach (var ct in CollectionTypes)
|
||||||
{
|
// {
|
||||||
document.AppendLine(@$"
|
// document.AppendLine(@$"
|
||||||
public static {ct}<{op.ReturnType}> operator /({op.TypeA} left, {ct}<{op.TypeB}> right) => right.MetricSelect(UU => left / UU);
|
// public static {ct}<{op.ReturnType}> operator /({op.TypeA} left, {ct}<{op.TypeB}> right) => right.MetricSelect(UU => left / UU);
|
||||||
");
|
//");
|
||||||
}
|
// }
|
||||||
document.Append("}");
|
// document.Append("}");
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
context.ReportDiagnostic(Diagnostic.Create(new(
|
// context.ReportDiagnostic(Diagnostic.Create(new(
|
||||||
"MSG0001",
|
// "MSG0001",
|
||||||
"Need a class with an attribute",
|
// "Need a class with an attribute",
|
||||||
$"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"",
|
// $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"",
|
||||||
"category",
|
// "category",
|
||||||
DiagnosticSeverity.Error,
|
// DiagnosticSeverity.Error,
|
||||||
true), null, ops.Key));
|
// true), null, ops.Key));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
foreach (var ops in divisions.GroupBy(op => op.TypeB))
|
// foreach (var ops in divisions.GroupBy(op => op.TypeB))
|
||||||
{
|
// {
|
||||||
var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key);
|
// var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key);
|
||||||
if (Class is not null)
|
// if (Class is not null)
|
||||||
{
|
// {
|
||||||
document.AppendLine();
|
// document.AppendLine();
|
||||||
document.AppendLine();
|
// document.AppendLine();
|
||||||
document.AppendLine(Class.Value.ClassHeader);
|
// document.AppendLine(Class.Value.ClassHeader);
|
||||||
document.AppendLine("{");
|
// document.AppendLine("{");
|
||||||
foreach (var op in ops)
|
// foreach (var op in ops)
|
||||||
foreach (var ct in CollectionTypes)
|
// foreach (var ct in CollectionTypes)
|
||||||
{
|
// {
|
||||||
document.AppendLine(@$"
|
// document.AppendLine(@$"
|
||||||
public static {ct}<{op.ReturnType}> operator /({ct}<{op.TypeA}> left, {op.TypeB} right) => left.MetricSelect(UU => UU / right);
|
// public static {ct}<{op.ReturnType}> operator /({ct}<{op.TypeA}> left, {op.TypeB} right) => left.MetricSelect(UU => UU / right);
|
||||||
");
|
//");
|
||||||
}
|
// }
|
||||||
document.Append("}");
|
// document.Append("}");
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
context.ReportDiagnostic(Diagnostic.Create(new(
|
// context.ReportDiagnostic(Diagnostic.Create(new(
|
||||||
"MSG0001",
|
// "MSG0001",
|
||||||
"Need a class with an attribute",
|
// "Need a class with an attribute",
|
||||||
$"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"",
|
// $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"",
|
||||||
"category",
|
// "category",
|
||||||
DiagnosticSeverity.Error,
|
// DiagnosticSeverity.Error,
|
||||||
true), null, ops.Key));
|
// true), null, ops.Key));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
context.AddSource($"operations.{ng.Key}.g", document.ToString());
|
// context.AddSource($"operations.{ng.Key}.g", document.ToString());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
public struct ClassData(string nameSpace, string className, string classHeader)
|
//public struct ClassData(string nameSpace, string className, string classHeader)
|
||||||
{
|
//{
|
||||||
public string NameSpace = nameSpace;
|
// public string NameSpace = nameSpace;
|
||||||
public string ClassName = className;
|
// public string ClassName = className;
|
||||||
public string ClassHeader = classHeader;
|
// public string ClassHeader = classHeader;
|
||||||
}
|
//}
|
||||||
public struct Operation(string operatorToken, string typeA, string typeB, string returnType)
|
//public struct Operation(string operatorToken, string typeA, string typeB, string returnType)
|
||||||
{
|
//{
|
||||||
public string ReturnType = returnType;
|
// public string ReturnType = returnType;
|
||||||
public string OperatorToken = operatorToken;
|
// public string OperatorToken = operatorToken;
|
||||||
public string TypeA = typeA;
|
// public string TypeA = typeA;
|
||||||
public string TypeB = typeB;
|
// public string TypeB = typeB;
|
||||||
}
|
//}
|
||||||
@@ -87,12 +87,12 @@ namespace QWERTYkez.Mensura
|
|||||||
string ns = info.Namespace;
|
string ns = info.Namespace;
|
||||||
|
|
||||||
// Здесь должен быть полный код из вашего файла XXXXXXXXXXXX.cs
|
// Здесь должен быть полный код из вашего файла XXXXXXXXXXXX.cs
|
||||||
// с заменой XXXXXXXXXXXXXX на {typeName}. Для краткости приведён скелет.
|
// с заменой {typeName} на {typeName}. Для краткости приведён скелет.
|
||||||
// Вы должны скопировать сюда всё содержимое вашего второго файла,
|
// Вы должны скопировать сюда всё содержимое вашего второго файла,
|
||||||
// заменив XXXXXXXXXXXXXX на {typeName}.
|
// заменив {typeName} на {typeName}.
|
||||||
string skeleton = @"
|
string skeleton = @"
|
||||||
global using {typeName} = QWERTYkez.Mensura.Units.{typeName};
|
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;
|
global using {typeName}Converter = QWERTYkez.Mensura.Units.{typeName}Converter;
|
||||||
|
|
||||||
using System.Globalization;
|
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 IsPositive => _Value >= 0;
|
||||||
[JsonIgnore, IgnoreDataMember] public bool IsGreaterThanZero => _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 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);
|
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;
|
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} MetricSum(this IEnumerable<{typeName}> units) => new(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} MetricAverage(this IEnumerable<{typeName}> units) => new(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} MetricMax(this IEnumerable<{typeName}> units) => new(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} 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} MetricSum(this IEnumerable<{typeName}?> units) => new(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} MetricAverage(this IEnumerable<{typeName}?> units) => new(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} MetricMax(this IEnumerable<{typeName}?> units) => new(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} 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)
|
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);
|
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
||||||
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
|
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 vectorSize = Vector<double>.Count;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -342,7 +337,7 @@ public static class {typeName}Extensions
|
|||||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||||
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
||||||
var vector = new Vector<double>(srcWindow);
|
var vector = new Vector<double>(srcWindow);
|
||||||
var multiplied = vector * vectorizedValue;
|
var multiplied = vector * vectorized_Value;
|
||||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||||
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
||||||
multiplied.CopyTo(dstWindow);
|
multiplied.CopyTo(dstWindow);
|
||||||
@@ -363,7 +358,7 @@ public static class {typeName}Extensions
|
|||||||
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
||||||
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
|
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 vectorSize = Vector<double>.Count;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -376,7 +371,7 @@ public static class {typeName}Extensions
|
|||||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||||
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
||||||
var vector = new Vector<double>(srcWindow);
|
var vector = new Vector<double>(srcWindow);
|
||||||
var multiplied = vector / vectorizedValue;
|
var multiplied = vector / vectorized_Value;
|
||||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||||
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
||||||
multiplied.CopyTo(dstWindow);
|
multiplied.CopyTo(dstWindow);
|
||||||
@@ -393,7 +388,7 @@ public static class {typeName}Extensions
|
|||||||
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
||||||
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
|
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; // Вектор из нулей для сравнения
|
var zeroVector = Vector<double>.Zero; // Вектор из нулей для сравнения
|
||||||
int vectorSize = Vector<double>.Count;
|
int vectorSize = Vector<double>.Count;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -414,7 +409,7 @@ public static class {typeName}Extensions
|
|||||||
throw new DivideByZeroException($""Обнаружен делитель, равный нулю, в районе индексов {i}..{i + vectorSize - 1}."");
|
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);
|
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||||
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
||||||
multiplied.CopyTo(dstWindow);
|
multiplied.CopyTo(dstWindow);
|
||||||
@@ -437,7 +432,7 @@ public static class {typeName}Extensions
|
|||||||
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
||||||
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
|
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 vectorSize = Vector<double>.Count;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -450,7 +445,7 @@ public static class {typeName}Extensions
|
|||||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||||
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
||||||
var vector = new Vector<double>(srcWindow);
|
var vector = new Vector<double>(srcWindow);
|
||||||
var multiplied = vector + vectorizedValue;
|
var multiplied = vector + vectorized_Value;
|
||||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||||
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
||||||
multiplied.CopyTo(dstWindow);
|
multiplied.CopyTo(dstWindow);
|
||||||
@@ -467,7 +462,7 @@ public static class {typeName}Extensions
|
|||||||
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
||||||
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
|
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 vectorSize = Vector<double>.Count;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -480,7 +475,7 @@ public static class {typeName}Extensions
|
|||||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||||
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
||||||
var vector = new Vector<double>(srcWindow);
|
var vector = new Vector<double>(srcWindow);
|
||||||
var multiplied = vector - vectorizedValue;
|
var multiplied = vector - vectorized_Value;
|
||||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||||
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
||||||
multiplied.CopyTo(dstWindow);
|
multiplied.CopyTo(dstWindow);
|
||||||
@@ -497,7 +492,7 @@ public static class {typeName}Extensions
|
|||||||
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
ReadOnlySpan<double> srcDouble = MemoryMarshal.Cast<{typeName}, double>(source);
|
||||||
Span<double> dstDouble = MemoryMarshal.Cast<{typeName}, double>(destination);
|
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 vectorSize = Vector<double>.Count;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -510,7 +505,7 @@ public static class {typeName}Extensions
|
|||||||
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
ref double currentSrc = ref Unsafe.Add(ref srcRef, i);
|
||||||
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
ReadOnlySpan<double> srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize);
|
||||||
var vector = new Vector<double>(srcWindow);
|
var vector = new Vector<double>(srcWindow);
|
||||||
var multiplied = vectorizedValue - vector;
|
var multiplied = vectorized_Value - vector;
|
||||||
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
ref double currentDst = ref Unsafe.Add(ref dstRef, i);
|
||||||
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
Span<double> dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize);
|
||||||
multiplied.CopyTo(dstWindow);
|
multiplied.CopyTo(dstWindow);
|
||||||
@@ -550,7 +545,7 @@ public static class {typeName}Extensions
|
|||||||
if (exp < 0)
|
if (exp < 0)
|
||||||
{
|
{
|
||||||
baseVector = Vector<double>.One / baseVector;
|
baseVector = Vector<double>.One / baseVector;
|
||||||
exp = -exp; // Внимание: может переполниться при int.MinValue, но для степеней это редчайший кейс
|
exp = -exp; // Внимание: может переполниться при int.Min_Value, но для степеней это редчайший кейс
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = Vector<double>.One;
|
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)
|
public static Tcoll Multiply<Tcoll>(this ICollection<{typeName}> units, double multiplicator)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -744,7 +739,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Multiply<Tcoll>(this ICollection<{typeName}?> units, double multiplicator)
|
public static Tcoll Multiply<Tcoll>(this ICollection<{typeName}?> units, double multiplicator)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -936,7 +931,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Divide<Tcoll>(this ICollection<{typeName}> units, double divisor)
|
public static Tcoll Divide<Tcoll>(this ICollection<{typeName}> units, double divisor)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -947,7 +942,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Divide<Tcoll>(this double dividend, ICollection<{typeName}> units)
|
public static Tcoll Divide<Tcoll>(this double dividend, ICollection<{typeName}> units)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -958,7 +953,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Divide<Tcoll>(this ICollection<{typeName}?> units, double divisor)
|
public static Tcoll Divide<Tcoll>(this ICollection<{typeName}?> units, double divisor)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -969,7 +964,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Divide<Tcoll>(this double dividend, ICollection<{typeName}?> units)
|
public static Tcoll Divide<Tcoll>(this double dividend, ICollection<{typeName}?> units)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1101,7 +1096,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Plus<Tcoll>(this ICollection<{typeName}> units, double summand)
|
public static Tcoll Plus<Tcoll>(this ICollection<{typeName}> units, double summand)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1114,7 +1109,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Plus<Tcoll>(this ICollection<{typeName}?> units, double summand)
|
public static Tcoll Plus<Tcoll>(this ICollection<{typeName}?> units, double summand)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1297,7 +1292,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Minus<Tcoll>(this ICollection<{typeName}> units, double subtrahend)
|
public static Tcoll Minus<Tcoll>(this ICollection<{typeName}> units, double subtrahend)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1308,7 +1303,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Minus<Tcoll>(this double minuend, ICollection<{typeName}> units)
|
public static Tcoll Minus<Tcoll>(this double minuend, ICollection<{typeName}> units)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1319,7 +1314,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Minus<Tcoll>(this ICollection<{typeName}?> units, double subtrahend)
|
public static Tcoll Minus<Tcoll>(this ICollection<{typeName}?> units, double subtrahend)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1330,7 +1325,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Minus<Tcoll>(this double minuend, ICollection<{typeName}?> units)
|
public static Tcoll Minus<Tcoll>(this double minuend, ICollection<{typeName}?> units)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1453,7 +1448,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units, int power)
|
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units, int power)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1464,7 +1459,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units, int power)
|
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units, int power)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1573,7 +1568,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units, double power)
|
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units, double power)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1584,7 +1579,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units, double power)
|
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units, double power)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1694,7 +1689,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units)
|
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}> units)
|
||||||
where Tcoll : class, ICollection<{typeName}>, new()
|
where Tcoll : class, ICollection<{typeName}>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
list.Capacity = units.Count;
|
||||||
@@ -1705,7 +1700,7 @@ public static class {typeName}Extensions
|
|||||||
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units)
|
public static Tcoll Pow<Tcoll>(this ICollection<{typeName}?> units)
|
||||||
where Tcoll : class, ICollection<{typeName}?>, new()
|
where Tcoll : class, ICollection<{typeName}?>, new()
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(units);
|
if (units is null) return null!;
|
||||||
var tColl = new Tcoll();
|
var tColl = new Tcoll();
|
||||||
if (tColl is List<{typeName}> list)
|
if (tColl is List<{typeName}> list)
|
||||||
list.Capacity = units.Count;
|
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)
|
public override {typeName} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
double doubleValue;
|
double double_Value;
|
||||||
|
|
||||||
if (reader.TokenType == JsonTokenType.String)
|
if (reader.TokenType == JsonTokenType.String)
|
||||||
{
|
{
|
||||||
// Безопасно парсим double из строки с поддержкой точки как разделителя
|
// Безопасно парсим 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})}."");
|
throw new JsonException($""Не удалось преобразовать строковое значение в double для метрики {nameof({typeName})}."");
|
||||||
}
|
}
|
||||||
@@ -1750,10 +1745,10 @@ public class {typeName}Converter : JsonConverter<{typeName}>
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Прямое быстрое чтение числа из JSON
|
// Прямое быстрое чтение числа из 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)
|
public override void Write(Utf8JsonWriter writer, {typeName} value, JsonSerializerOptions options)
|
||||||
@@ -1774,12 +1769,12 @@ public class {typeName}Converter : JsonConverter<{typeName}>
|
|||||||
{
|
{
|
||||||
string propertyName = reader.GetString()!;
|
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})}."");
|
throw new JsonException($""Невалидное числовое значение в ключе свойства JSON: '{propertyName}' для метрики {nameof({typeName})}."");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new(doubleValue);
|
return new(double_Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
|||||||
global using PogonMass = QWERTYkez.Mensura.Units.Pogon.PogonMass;
|
#if DEBUG
|
||||||
|
global using PogonMass = QWERTYkez.Mensura.Units.Pogon.PogonMass;
|
||||||
global using PogonMassExtensions = QWERTYkez.Mensura.Units.Pogon.PogonMassExtensions;
|
global using PogonMassExtensions = QWERTYkez.Mensura.Units.Pogon.PogonMassExtensions;
|
||||||
global using PogonMassConverter = QWERTYkez.Mensura.Units.Pogon.PogonMassConverter;
|
global using PogonMassConverter = QWERTYkez.Mensura.Units.Pogon.PogonMassConverter;
|
||||||
|
|
||||||
@@ -20,8 +21,7 @@ namespace QWERTYkez.Mensura.Units
|
|||||||
if (len == 0) return [];
|
if (len == 0) return [];
|
||||||
|
|
||||||
var result = new Mass[len];
|
var result = new Mass[len];
|
||||||
for (int i = 0; i < len; i++)
|
PogonMassExtensions.MultiplyCore(left, right, result);
|
||||||
result[i] = right * left[i];
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
public static Mass[] operator *(PogonMass[] left, Length? right)
|
public static Mass[] operator *(PogonMass[] left, Length? right)
|
||||||
@@ -367,7 +367,7 @@ namespace QWERTYkez.Mensura.Units.Pogon
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal static void MultiplyCore(ReadOnlySpan<PogonMass> source, Length value, Span<Mass> destination)
|
internal static void MultiplyCore(this ReadOnlySpan<PogonMass> source, Length value, Span<Mass> destination)
|
||||||
{
|
{
|
||||||
var dVal = value._Value;
|
var dVal = value._Value;
|
||||||
int len = source.Length;
|
int len = source.Length;
|
||||||
@@ -398,7 +398,7 @@ namespace QWERTYkez.Mensura.Units.Pogon
|
|||||||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * dVal;
|
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) * dVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal static void MultiplyCore(ReadOnlySpan<Length> source, PogonMass value, Span<Mass> destination)
|
internal static void MultiplyCore(this ReadOnlySpan<Length> source, PogonMass value, Span<Mass> destination)
|
||||||
{
|
{
|
||||||
var dVal = value._Value;
|
var dVal = value._Value;
|
||||||
int len = source.Length;
|
int len = source.Length;
|
||||||
@@ -431,7 +431,7 @@ namespace QWERTYkez.Mensura.Units.Pogon
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static void DivideCore(ReadOnlySpan<Mass> source, PogonMass divisor, Span<Length> destination)
|
internal static void DivideCore(this ReadOnlySpan<Mass> source, PogonMass divisor, Span<Length> destination)
|
||||||
{
|
{
|
||||||
// 1. Проверка на ноль
|
// 1. Проверка на ноль
|
||||||
if (divisor.IsZero || divisor.IsNaN)
|
if (divisor.IsZero || divisor.IsNaN)
|
||||||
@@ -466,7 +466,7 @@ namespace QWERTYkez.Mensura.Units.Pogon
|
|||||||
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) / dVal;
|
Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) / dVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal static void DivideCore(Mass dividend, ReadOnlySpan<PogonMass> source, Span<Length> destination)
|
internal static void DivideCore(this Mass dividend, ReadOnlySpan<PogonMass> source, Span<Length> destination)
|
||||||
{
|
{
|
||||||
var dVal = dividend._Value;
|
var dVal = dividend._Value;
|
||||||
int len = source.Length;
|
int len = source.Length;
|
||||||
@@ -566,3 +566,4 @@ namespace QWERTYkez.Mensura.Units.Pogon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
namespace QWERTYkez.Mensura.Units.Pogon;
|
#if DEBUG
|
||||||
|
namespace QWERTYkez.Mensura.Units.Pogon;
|
||||||
|
|
||||||
public readonly partial record struct PogonMass
|
public readonly partial record struct PogonMass
|
||||||
{
|
{
|
||||||
@@ -31,3 +32,4 @@ public readonly partial record struct PogonMass
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,74 +1,74 @@
|
|||||||
//namespace QWERTYkez.Mensura.Units;
|
#if DEBUG
|
||||||
|
namespace QWERTYkez.Mensura.Units;
|
||||||
|
|
||||||
///// <summary>
|
/// <summary>
|
||||||
///// Base value is MilliMeters
|
/// Base value is MilliMeters
|
||||||
///// </summary>
|
/// </summary>
|
||||||
//[UnitOperatorsGenerator, DebuggerDisplay("mm = {_MilliMeters.ToString(\"0.###\")}, m = {Meters.ToString(\"0.###\")}")]
|
[DebuggerDisplay("mm = {_MilliMeters.ToString(\"0.###\")}, m = {Meters.ToString(\"0.###\")}")]
|
||||||
//public readonly partial record struct XXXXXXXXXXXXXX
|
public readonly partial record struct XXXXXXXXXXXXXX
|
||||||
//{
|
{
|
||||||
// public static XXXXXXXXXXXXXX MilliMeter { get; } = new(1);
|
public static XXXXXXXXXXXXXX MilliMeter { get; } = new(1);
|
||||||
//#pragma warning disable IDE1006 // _Подчеркивание для обозначения того, что это базовая единица
|
[NotMapped, JsonIgnore] public double _MilliMeters { get => _Value; init => _Value = value; }
|
||||||
// [NotMapped, JsonIgnore] public double _MilliMeters { get => _Value; init => _Value = value; }
|
|
||||||
//#pragma warning restore IDE1006
|
|
||||||
|
|
||||||
|
|
||||||
// public static XXXXXXXXXXXXXX CentiMeter { get; } = new(XXXXXXXXXXXXXXConv.CentiMeters.To(1));
|
public static XXXXXXXXXXXXXX CentiMeter { get; } = new(XXXXXXXXXXXXXXConv.CentiMeters.To(1));
|
||||||
// [NotMapped, JsonIgnore] public double CentiMeters
|
[NotMapped, JsonIgnore] public double CentiMeters
|
||||||
// {
|
{
|
||||||
// get => XXXXXXXXXXXXXXConv.CentiMeters.From(_Value);
|
get => XXXXXXXXXXXXXXConv.CentiMeters.From(_Value);
|
||||||
// init
|
init
|
||||||
// {
|
{
|
||||||
// XXXXXXXXXXXXXX aaa = new();
|
XXXXXXXXXXXXXX aaa = new();
|
||||||
// XXXXXXXXXXXXXX bbb = new();
|
XXXXXXXXXXXXXX bbb = new();
|
||||||
|
|
||||||
// if (aaa != bbb || aaa == bbb)
|
if (aaa != bbb || aaa == bbb)
|
||||||
// {
|
{
|
||||||
|
|
||||||
// }
|
}
|
||||||
|
|
||||||
// _Value = XXXXXXXXXXXXXXConv.CentiMeters.To(value);
|
_Value = XXXXXXXXXXXXXXConv.CentiMeters.To(value);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// public static XXXXXXXXXXXXXX DeciMeter { get; } = new(XXXXXXXXXXXXXXConv.DeciMeters.To(1));
|
public static XXXXXXXXXXXXXX DeciMeter { get; } = new(XXXXXXXXXXXXXXConv.DeciMeters.To(1));
|
||||||
// [NotMapped, JsonIgnore] public double DeciMeters
|
[NotMapped, JsonIgnore] public double DeciMeters
|
||||||
// {
|
{
|
||||||
// get => XXXXXXXXXXXXXXConv.DeciMeters.From(_Value);
|
get => XXXXXXXXXXXXXXConv.DeciMeters.From(_Value);
|
||||||
// init => _Value = XXXXXXXXXXXXXXConv.DeciMeters.To(value);
|
init => _Value = XXXXXXXXXXXXXXConv.DeciMeters.To(value);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// public static XXXXXXXXXXXXXX Meter { get; } = new(XXXXXXXXXXXXXXConv.Meters.To(1));
|
public static XXXXXXXXXXXXXX Meter { get; } = new(XXXXXXXXXXXXXXConv.Meters.To(1));
|
||||||
// [NotMapped, JsonIgnore] public double Meters
|
[NotMapped, JsonIgnore] public double Meters
|
||||||
// {
|
{
|
||||||
// get => XXXXXXXXXXXXXXConv.Meters.From(_Value);
|
get => XXXXXXXXXXXXXXConv.Meters.From(_Value);
|
||||||
// init => _Value = XXXXXXXXXXXXXXConv.Meters.To(value);
|
init => _Value = XXXXXXXXXXXXXXConv.Meters.To(value);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// public static XXXXXXXXXXXXXX KiloMeter { get; } = new(XXXXXXXXXXXXXXConv.KiloMeters.To(1));
|
public static XXXXXXXXXXXXXX KiloMeter { get; } = new(XXXXXXXXXXXXXXConv.KiloMeters.To(1));
|
||||||
// [NotMapped, JsonIgnore] public double KiloMeters
|
[NotMapped, JsonIgnore] public double KiloMeters
|
||||||
// {
|
{
|
||||||
// get => XXXXXXXXXXXXXXConv.KiloMeters.From(_Value);
|
get => XXXXXXXXXXXXXXConv.KiloMeters.From(_Value);
|
||||||
// init => _Value = XXXXXXXXXXXXXXConv.KiloMeters.To(value);
|
init => _Value = XXXXXXXXXXXXXXConv.KiloMeters.To(value);
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
// public XXXXXXXXXXXXXX AddMilliMeters(double value) => new(_Value + value);
|
public XXXXXXXXXXXXXX AddMilliMeters(double value) => new(_Value + value);
|
||||||
// public XXXXXXXXXXXXXX AddCentiMeters(double value) => new(_Value + XXXXXXXXXXXXXXConv.CentiMeters.To(value));
|
public XXXXXXXXXXXXXX AddCentiMeters(double value) => new(_Value + XXXXXXXXXXXXXXConv.CentiMeters.To(value));
|
||||||
// public XXXXXXXXXXXXXX AddDeciMeters(double value) => new(_Value + XXXXXXXXXXXXXXConv.DeciMeters.To(value));
|
public XXXXXXXXXXXXXX AddDeciMeters(double value) => new(_Value + XXXXXXXXXXXXXXConv.DeciMeters.To(value));
|
||||||
// public XXXXXXXXXXXXXX AddMeters(double value) => new(_Value + XXXXXXXXXXXXXXConv.Meters.To(value));
|
public XXXXXXXXXXXXXX AddMeters(double value) => new(_Value + XXXXXXXXXXXXXXConv.Meters.To(value));
|
||||||
// public XXXXXXXXXXXXXX AddKiloMeters(double value) => new(_Value + XXXXXXXXXXXXXXConv.KiloMeters.To(value));
|
public XXXXXXXXXXXXXX AddKiloMeters(double value) => new(_Value + XXXXXXXXXXXXXXConv.KiloMeters.To(value));
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
|
||||||
//internal readonly struct XXXXXXXXXXXXXXConv
|
internal readonly struct XXXXXXXXXXXXXXConv
|
||||||
//{
|
{
|
||||||
// private XXXXXXXXXXXXXXConv(double multiplicator) => this.Multiplicator = multiplicator;
|
private XXXXXXXXXXXXXXConv(double multiplicator) => this.Multiplicator = multiplicator;
|
||||||
// public double To(double value) => value * Multiplicator;
|
public double To(double value) => value * Multiplicator;
|
||||||
// public double From(double value) => value / Multiplicator;
|
public double From(double value) => value / Multiplicator;
|
||||||
// public double Multiplicator { get; init; }
|
public double Multiplicator { get; init; }
|
||||||
// public static XXXXXXXXXXXXXXConv MilliMeters { get; } = new(1);
|
public static XXXXXXXXXXXXXXConv MilliMeters { get; } = new(1);
|
||||||
// public static XXXXXXXXXXXXXXConv CentiMeters { get; } = new(10);
|
public static XXXXXXXXXXXXXXConv CentiMeters { get; } = new(10);
|
||||||
// public static XXXXXXXXXXXXXXConv DeciMeters { get; } = new(100);
|
public static XXXXXXXXXXXXXXConv DeciMeters { get; } = new(100);
|
||||||
// public static XXXXXXXXXXXXXXConv Meters { get; } = new(1000);
|
public static XXXXXXXXXXXXXXConv Meters { get; } = new(1000);
|
||||||
// public static XXXXXXXXXXXXXXConv KiloMeters { get; } = new(1000000);
|
public static XXXXXXXXXXXXXXConv KiloMeters { get; } = new(1000000);
|
||||||
//}
|
}
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user