From 4ff3cc704249a6d5e798620da4cca2b8b942859b Mon Sep 17 00:00:00 2001 From: melekhin Date: Fri, 5 Jun 2026 12:13:35 +0700 Subject: [PATCH] 26,06,05 --- .../ComplexUnitGenerator.cs | 638 +++++++++ .../OperatorsGenerator.cs | 393 +++--- .../QWERTYkez.Mensura.Generator.csproj | 9 +- ...OperatorsGenerator.cs => UnitGenerator.cs} | 14 +- QWERTYkez.Mensura/Operators.cs | 421 +++--- QWERTYkez.Mensura/Units/Angle.cs | 14 +- QWERTYkez.Mensura/Units/Area.cs | 15 +- QWERTYkez.Mensura/Units/Boost.cs | 16 +- .../Units/Complex/ForceLinear.cs | 78 ++ .../Units/Complex/ForceVolumetric.cs | 56 + QWERTYkez.Mensura/Units/Complex/MassLinear.cs | 82 ++ .../Units/Complex/MassVolumetric (Density).cs | 59 + QWERTYkez.Mensura/Units/Force.cs | 14 +- QWERTYkez.Mensura/Units/Frequency.cs | 14 +- QWERTYkez.Mensura/Units/Length.cs | 17 +- QWERTYkez.Mensura/Units/Mass.cs | 14 +- QWERTYkez.Mensura/Units/MassPerSquare.cs | 14 +- QWERTYkez.Mensura/Units/Pogon/PogonForce.cs | 14 - QWERTYkez.Mensura/Units/Pogon/PogonMass.cs | 14 - .../Units/Pogon/PogonXXXXXXXX.Gen.cs | 1238 +++++++---------- .../Units/Pogon/PogonXXXXXXXX.Ref.cs | 100 +- QWERTYkez.Mensura/Units/Pressure.cs | 14 +- QWERTYkez.Mensura/Units/Speed.cs | 14 +- QWERTYkez.Mensura/Units/Time.cs | 14 +- QWERTYkez.Mensura/Units/Torque.cs | 14 +- QWERTYkez.Mensura/Units/Udel/UdelForce.cs | 16 - .../Units/Udel/UdelMass (Density).cs | 16 - QWERTYkez.Mensura/Units/Voltage.cs | 14 +- QWERTYkez.Mensura/Units/Volume.cs | 14 +- QWERTYkez.Mensura/globals.cs | 3 +- 30 files changed, 1875 insertions(+), 1478 deletions(-) create mode 100644 QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs rename QWERTYkez.Mensura.Generator/{UnitOperatorsGenerator.cs => UnitGenerator.cs} (96%) create mode 100644 QWERTYkez.Mensura/Units/Complex/ForceLinear.cs create mode 100644 QWERTYkez.Mensura/Units/Complex/ForceVolumetric.cs create mode 100644 QWERTYkez.Mensura/Units/Complex/MassLinear.cs create mode 100644 QWERTYkez.Mensura/Units/Complex/MassVolumetric (Density).cs delete mode 100644 QWERTYkez.Mensura/Units/Pogon/PogonForce.cs delete mode 100644 QWERTYkez.Mensura/Units/Pogon/PogonMass.cs delete mode 100644 QWERTYkez.Mensura/Units/Udel/UdelForce.cs delete mode 100644 QWERTYkez.Mensura/Units/Udel/UdelMass (Density).cs diff --git a/QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs b/QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs new file mode 100644 index 0000000..c470fe8 --- /dev/null +++ b/QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs @@ -0,0 +1,638 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; +using System.Text; + +namespace G; + +[Generator] +public class ComplexUnitGenerator : IIncrementalGenerator +{ + private const string AttributeName = "ComplexUnitGenerator"; + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + // 1. Генерируем определение атрибута + context.RegisterPostInitializationOutput(ctx => + { + string attributeSource = @" +namespace QWERTYkez.Mensura +{ + [System.AttributeUsage(System.AttributeTargets.Struct, AllowMultiple = false)] + public sealed class ComplexUnitGeneratorAttribute : System.Attribute + { + public string TypeNameA { get; } + public string TypeNameB { get; } + public string TypeNameZ { get; } + + public ComplexUnitGeneratorAttribute(string typeNameA, string typeNameB, string typeNameZ) + { + TypeNameA = typeNameA; + TypeNameB = typeNameB; + TypeNameZ = typeNameZ; + } + } +}"; + ctx.AddSource(".ComplexUnitGeneratorAttribute.g.cs", SourceText.From(attributeSource, Encoding.UTF8)); + }); + + // 2. Ищем все readonly partial record struct с этим атрибутом + var structsProvider = context.SyntaxProvider + .CreateSyntaxProvider( + predicate: static (node, _) => IsTargetStruct(node), + transform: static (ctx, _) => GetStructInfo(ctx)) + .Where(info => info.HasValue) + .Select((info, _) => info!.Value) + .Collect(); + + // 3. Регистрируем вывод для каждой найденной структуры + context.RegisterSourceOutput(structsProvider, (spc, structs) => + { + foreach (var structInfo in structs) + { + string generatedCode = GeneratePartial(structInfo.TypeName, structInfo.Namespace, + structInfo.TypeNameA, structInfo.TypeNameB, structInfo.TypeNameZ); + spc.AddSource($"{structInfo.TypeName}.g.cs", SourceText.From(generatedCode, Encoding.UTF8)); + } + }); + } + + private static bool IsTargetStruct(SyntaxNode node) + { + if (node is not RecordDeclarationSyntax record) + return false; + + // Должен быть record struct с модификаторами readonly и partial + if (!record.Modifiers.Any(SyntaxKind.ReadOnlyKeyword) || + !record.Modifiers.Any(SyntaxKind.PartialKeyword) || + !record.Keyword.IsKind(SyntaxKind.RecordKeyword) || + !record.ClassOrStructKeyword.IsKind(SyntaxKind.StructKeyword)) + return false; + + // Проверяем наличие атрибута [ComplexUnitGenerator] или [ComplexUnitGeneratorAttribute] + foreach (var attrList in record.AttributeLists) + foreach (var attr in attrList.Attributes) + { + string name = attr.Name.ToString(); + if (name == AttributeName || name == AttributeName + "Attribute") + return true; + } + return false; + } + + private static StructInfo? GetStructInfo(GeneratorSyntaxContext context) + { + var record = (RecordDeclarationSyntax)context.Node; + var semanticModel = context.SemanticModel; + if (semanticModel.GetDeclaredSymbol(record) is not INamedTypeSymbol typeSymbol) + return null; + + string namespaceName = typeSymbol.ContainingNamespace?.ToString() ?? ""; + if (string.IsNullOrEmpty(namespaceName)) + return null; + + // Извлекаем аргументы атрибута + string typeNameA = null; + string typeNameB = null; + string typeNameZ = null; + + foreach (var attrList in record.AttributeLists) + foreach (var attr in attrList.Attributes) + { + string name = attr.Name.ToString(); + if (name == AttributeName || name == AttributeName + "Attribute") + { + // Ищем аргументы конструктора + var args = attr.ArgumentList?.Arguments; + if (args.HasValue && args.Value.Count >= 3) + { + typeNameA = GetStringFromExpression(args.Value[0].Expression, semanticModel); + typeNameB = GetStringFromExpression(args.Value[1].Expression, semanticModel); + typeNameZ = GetStringFromExpression(args.Value[2].Expression, semanticModel); + } + break; + } + } + + if (typeNameA == null || typeNameB == null || typeNameZ == null) + return null; + + return new StructInfo(namespaceName, typeSymbol.Name, typeNameA, typeNameB, typeNameZ); + } + + private static string GetStringFromExpression(ExpressionSyntax expr, SemanticModel semanticModel) + { + // Поддерживаем строковые литералы и константы + if (expr is LiteralExpressionSyntax literal && literal.IsKind(SyntaxKind.StringLiteralExpression)) + return literal.Token.ValueText; + + // Если это доступ к константе, пытаемся вычислить через семантику + var constantValue = semanticModel.GetConstantValue(expr); + if (constantValue.HasValue && constantValue.Value is string s) + return s; + + return null; + } + + private static string GeneratePartial(string typeName, string ns, string typeNameA, string typeNameB, string typeNameZ) + { + // Шаблон, который вы вставите сами. + // В нём используйте {typeName}, {ns}, {typeNameA}, {typeNameB}, {typeNameZ} + // Например: + string template = @" +global using {typeNameZ}Extensions = QWERTYkez.Mensura.Units.Complex.{typeNameZ}Extensions; +global using {typeNameZ}Converter = QWERTYkez.Mensura.Units.Complex.{typeNameZ}Converter; +global using {typeNameZ} = QWERTYkez.Mensura.Units.Complex.{typeNameZ}; + +using System.Globalization; +using System.Runtime.Serialization; + +namespace QWERTYkez.Mensura.Units +{ + public readonly partial record struct {typeNameB} + { + public static {typeNameZ} operator /({typeNameA} left, {typeNameB} right) => new(left._Value / right._Value); + public static {typeNameZ} operator /({typeNameA}? left, {typeNameB} right) => new(left.Protected() / right._Value); + public static {typeNameZ} operator /({typeNameA} left, {typeNameB}? right) => new(left._Value / right.Protected()); + public static {typeNameZ} operator /({typeNameA}? left, {typeNameB}? right) => new(left.Protected() / right.Protected()); + + + // === Array === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator + *({typeNameZ}[] units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator + *({typeNameZ}?[] units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator + *({typeNameB} multiplicator, {typeNameZ}[] units) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator + *({typeNameB} multiplicator, {typeNameZ}?[] units) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator *({typeNameZ}[] units, {typeNameB}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new {typeNameA}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator *({typeNameZ}?[] units, {typeNameB}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new {typeNameA}?[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator *({typeNameB}? multiplicator, {typeNameZ}[] units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new {typeNameA}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator *({typeNameB}? multiplicator, {typeNameZ}?[] units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new {typeNameA}?[units.Length]); + + // === List === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator + *(List<{typeNameZ}> units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator + *(List<{typeNameZ}?> units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator + *({typeNameB} multiplicator, List<{typeNameZ}> units) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator + *({typeNameB} multiplicator, List<{typeNameZ}?> units) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator *(List<{typeNameZ}> units, {typeNameB}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List<{typeNameA}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator *(List<{typeNameZ}?> units, {typeNameB}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List<{typeNameA}?>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator *({typeNameB}? multiplicator, List<{typeNameZ}> units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List<{typeNameA}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator *({typeNameB}? multiplicator, List<{typeNameZ}?> units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List<{typeNameA}?>(units.Count)); + + // === IEnumerable === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator + *(IEnumerable<{typeNameZ}> units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator + *(IEnumerable<{typeNameZ}?> units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator + *({typeNameB} multiplicator, IEnumerable<{typeNameZ}> units) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator + *({typeNameB} multiplicator, IEnumerable<{typeNameZ}?> units) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator *(IEnumerable<{typeNameZ}> units, {typeNameB}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new {typeNameA}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator *(IEnumerable<{typeNameZ}?> units, {typeNameB}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameA}?)null : new {typeNameA}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator *({typeNameB}? multiplicator, IEnumerable<{typeNameZ}> units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new {typeNameA}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator *({typeNameB}? multiplicator, IEnumerable<{typeNameZ}?> units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameA}?)null : new {typeNameA}(0d))); + + + + + + + + + + // === Array === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator + /({typeNameA}[] units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator + /({typeNameA}?[] units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator + /({typeNameB} dividend, {typeNameA}[] units) => dividend._Value.Divide<{typeNameA}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator + /({typeNameB} dividend, {typeNameA}?[] units) => dividend._Value.Divide<{typeNameA}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator /({typeNameA}[] units, {typeNameB}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new {typeNameZ}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator /({typeNameA}?[] units, {typeNameB}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new {typeNameZ}?[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator /({typeNameB}? dividend, {typeNameA}[] units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new {typeNameZ}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator /({typeNameB}? dividend, {typeNameA}?[] units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new {typeNameZ}?[units.Length]); + + // === List === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator + /(List<{typeNameA}> units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator + /(List<{typeNameA}?> units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator + /({typeNameB} dividend, List<{typeNameA}> units) => dividend._Value.Divide<{typeNameA}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator + /({typeNameB} dividend, List<{typeNameA}?> units) => dividend._Value.Divide<{typeNameA}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator /(List<{typeNameA}> units, {typeNameB}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List<{typeNameZ}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator /(List<{typeNameA}?> units, {typeNameB}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List<{typeNameZ}?>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator /({typeNameB}? dividend, List<{typeNameA}> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List<{typeNameZ}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator /({typeNameB}? dividend, List<{typeNameA}?> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List<{typeNameZ}?>(units.Count)); + + // === IEnumerable === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator + /(IEnumerable<{typeNameA}> units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator + /(IEnumerable<{typeNameA}?> units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator + /({typeNameB} dividend, IEnumerable<{typeNameA}> units) => dividend._Value.Divide<{typeNameA}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator + /({typeNameB} dividend, IEnumerable<{typeNameA}?> units) => dividend._Value.Divide<{typeNameA}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator /(IEnumerable<{typeNameA}> units, {typeNameB}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => new {typeNameZ}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator /(IEnumerable<{typeNameA}?> units, {typeNameB}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameZ}?)null : new {typeNameZ}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator /({typeNameB}? dividend, IEnumerable<{typeNameA}> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => new {typeNameZ}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator /({typeNameB}? dividend, IEnumerable<{typeNameA}?> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameZ}?)null : new {typeNameZ}(0d))); + } + public readonly partial record struct {typeNameA} + { + // === Array === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator + /({typeNameZ}[] units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator + /({typeNameZ}?[] units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator + /({typeNameA} dividend, {typeNameZ}[] units) => dividend._Value.Divide<{typeNameZ}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator + /({typeNameA} dividend, {typeNameZ}?[] units) => dividend._Value.Divide<{typeNameZ}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator /({typeNameZ}[] units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new {typeNameB}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator /({typeNameZ}?[] units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new {typeNameB}?[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator /({typeNameA}? dividend, {typeNameZ}[] units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new {typeNameB}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator /({typeNameA}? dividend, {typeNameZ}?[] units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new {typeNameB}?[units.Length]); + + // === List === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator + /(List<{typeNameZ}> units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator + /(List<{typeNameZ}?> units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator + /({typeNameA} dividend, List<{typeNameZ}> units) => dividend._Value.Divide<{typeNameZ}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator + /({typeNameA} dividend, List<{typeNameZ}?> units) => dividend._Value.Divide<{typeNameZ}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator /(List<{typeNameZ}> units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List<{typeNameB}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator /(List<{typeNameZ}?> units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List<{typeNameB}?>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator /({typeNameA}? dividend, List<{typeNameZ}> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List<{typeNameB}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator /({typeNameA}? dividend, List<{typeNameZ}?> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List<{typeNameB}?>(units.Count)); + + // === IEnumerable === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator + /(IEnumerable<{typeNameZ}> units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator + /(IEnumerable<{typeNameZ}?> units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator + /({typeNameA} dividend, IEnumerable<{typeNameZ}> units) => dividend._Value.Divide<{typeNameZ}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator + /({typeNameA} dividend, IEnumerable<{typeNameZ}?> units) => dividend._Value.Divide<{typeNameZ}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator /(IEnumerable<{typeNameZ}> units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => new {typeNameB}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator /(IEnumerable<{typeNameZ}?> units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameB}?)null : new {typeNameB}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator /({typeNameA}? dividend, IEnumerable<{typeNameZ}> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => new {typeNameB}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator /({typeNameA}? dividend, IEnumerable<{typeNameZ}?> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameB}?)null : new {typeNameB}(0d))); + + + + + + + + + + // === Array === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator + /({typeNameB}[] units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator + /({typeNameB}?[] units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator + /({typeNameA} dividend, {typeNameB}[] units) => dividend._Value.Divide<{typeNameB}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator + /({typeNameA} dividend, {typeNameB}?[] units) => dividend._Value.Divide<{typeNameB}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator /({typeNameB}[] units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new {typeNameZ}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator /({typeNameB}?[] units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new {typeNameZ}?[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator /({typeNameA}? dividend, {typeNameB}[] units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new {typeNameZ}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator /({typeNameA}? dividend, {typeNameB}?[] units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new {typeNameZ}?[units.Length]); + + // === List === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator + /(List<{typeNameB}> units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator + /(List<{typeNameB}?> units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator + /({typeNameA} dividend, List<{typeNameB}> units) => dividend._Value.Divide<{typeNameB}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator + /({typeNameA} dividend, List<{typeNameB}?> units) => dividend._Value.Divide<{typeNameB}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator /(List<{typeNameB}> units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List<{typeNameZ}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator /(List<{typeNameB}?> units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List<{typeNameZ}?>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator /({typeNameA}? dividend, List<{typeNameB}> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List<{typeNameZ}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator /({typeNameA}? dividend, List<{typeNameB}?> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List<{typeNameZ}?>(units.Count)); + + // === IEnumerable === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator + /(IEnumerable<{typeNameB}> units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator + /(IEnumerable<{typeNameB}?> units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator + /({typeNameA} dividend, IEnumerable<{typeNameB}> units) => dividend._Value.Divide<{typeNameB}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator + /({typeNameA} dividend, IEnumerable<{typeNameB}?> units) => dividend._Value.Divide<{typeNameB}, {typeNameZ}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator /(IEnumerable<{typeNameB}> units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => new {typeNameZ}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator /(IEnumerable<{typeNameB}?> units, {typeNameA}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameZ}?)null : new {typeNameZ}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator /({typeNameA}? dividend, IEnumerable<{typeNameB}> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => new {typeNameZ}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator /({typeNameA}? dividend, IEnumerable<{typeNameB}?> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameZ}?)null : new {typeNameZ}(0d))); + } +} + +namespace QWERTYkez.Mensura.Units.Complex +{ + [JsonConverter(typeof({typeNameZ}Converter))] + public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, IEquatable<{typeNameZ}>, IMensuraUnit + { + + [JsonInclude, DataMember, JsonPropertyName(""v""), Obsolete] // для JSON / EF на случай сбоев, если пробелма с _Value + internal double Value { get => _Value; init => _Value = value; } + internal readonly double _Value; + internal {typeNameZ}(double value) => _Value = value; + + + [NotMapped, JsonIgnore] internal {typeNameA} PerValue + { get => ({typeNameA})_Value; init => _Value = (double)value; } + + + + [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 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 {typeNameA} operator *({typeNameZ} left, {typeNameB} right) => new(left._Value * right._Value); + public static {typeNameA} operator *({typeNameZ}? left, {typeNameB} right) => new(left.Protected() * right._Value); + public static {typeNameA} operator *({typeNameZ} left, {typeNameB}? right) => new(left._Value * right.Protected()); + public static {typeNameA} operator *({typeNameZ}? left, {typeNameB}? right) => new(left.Protected() * right.Protected()); + + public static {typeNameA} operator *({typeNameB} left, {typeNameZ} right) => new(right._Value * left._Value); + public static {typeNameA} operator *({typeNameB}? left, {typeNameZ} right) => new(right._Value * left.Protected()); + public static {typeNameA} operator *({typeNameB} left, {typeNameZ}? right) => new(right.Protected() * left._Value); + public static {typeNameA} operator *({typeNameB}? left, {typeNameZ}? right) => new(right.Protected() * left.Protected()); + + public static {typeNameB} operator /({typeNameA} left, {typeNameZ} right) => new(left._Value / right._Value); + public static {typeNameB} operator /({typeNameA}? left, {typeNameZ} right) => new(left.Protected() / right._Value); + public static {typeNameB} operator /({typeNameA} left, {typeNameZ}? right) => new(left._Value / right.Protected()); + public static {typeNameB} operator /({typeNameA}? left, {typeNameZ}? right) => new(left.Protected() / right.Protected()); + + + + + + + + + // === Array === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator + *({typeNameB}[] units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator + *({typeNameB}?[] units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator + *({typeNameZ} multiplicator, {typeNameB}[] units) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator + *({typeNameZ} multiplicator, {typeNameB}?[] units) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator *({typeNameB}[] units, {typeNameZ}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new {typeNameA}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator *({typeNameB}?[] units, {typeNameZ}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new {typeNameA}?[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator *({typeNameZ}? multiplicator, {typeNameB}[] units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new {typeNameA}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator *({typeNameZ}? multiplicator, {typeNameB}?[] units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new {typeNameA}?[units.Length]); + + // === List === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator + *(List<{typeNameB}> units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator + *(List<{typeNameB}?> units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator + *({typeNameZ} multiplicator, List<{typeNameB}> units) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator + *({typeNameZ} multiplicator, List<{typeNameB}?> units) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator *(List<{typeNameB}> units, {typeNameZ}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List<{typeNameA}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator *(List<{typeNameB}?> units, {typeNameZ}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List<{typeNameA}?>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator *({typeNameZ}? multiplicator, List<{typeNameB}> units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List<{typeNameA}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator *({typeNameZ}? multiplicator, List<{typeNameB}?> units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List<{typeNameA}?>(units.Count)); + + // === IEnumerable === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator + *(IEnumerable<{typeNameB}> units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator + *(IEnumerable<{typeNameB}?> units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator + *({typeNameZ} multiplicator, IEnumerable<{typeNameB}> units) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator + *({typeNameZ} multiplicator, IEnumerable<{typeNameB}?> units) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator *(IEnumerable<{typeNameB}> units, {typeNameZ}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new {typeNameA}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator *(IEnumerable<{typeNameB}?> units, {typeNameZ}? multiplicator) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameA}?)null : new {typeNameA}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator *({typeNameZ}? multiplicator, IEnumerable<{typeNameB}> units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new {typeNameA}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator *({typeNameZ}? multiplicator, IEnumerable<{typeNameB}?> units) => + multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameA}?)null : new {typeNameA}(0d))); + + + + + + + // === Array === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator + /({typeNameA}[] units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator + /({typeNameA}?[] units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator + /({typeNameZ} dividend, {typeNameA}[] units) => dividend._Value.Divide<{typeNameA}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator + /({typeNameZ} dividend, {typeNameA}?[] units) => dividend._Value.Divide<{typeNameA}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator /({typeNameA}[] units, {typeNameZ}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new {typeNameB}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator /({typeNameA}?[] units, {typeNameZ}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new {typeNameB}?[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator /({typeNameZ}? dividend, {typeNameA}[] units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new {typeNameB}[units.Length]); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator /({typeNameZ}? dividend, {typeNameA}?[] units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new {typeNameB}?[units.Length]); + + // === List === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator + /(List<{typeNameA}> units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator + /(List<{typeNameA}?> units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator + /({typeNameZ} dividend, List<{typeNameA}> units) => dividend._Value.Divide<{typeNameA}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator + /({typeNameZ} dividend, List<{typeNameA}?> units) => dividend._Value.Divide<{typeNameA}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator /(List<{typeNameA}> units, {typeNameZ}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List<{typeNameB}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator /(List<{typeNameA}?> units, {typeNameZ}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List<{typeNameB}?>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator /({typeNameZ}? dividend, List<{typeNameA}> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List<{typeNameB}>(units.Count)); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator /({typeNameZ}? dividend, List<{typeNameA}?> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List<{typeNameB}?>(units.Count)); + + // === IEnumerable === + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator + /(IEnumerable<{typeNameA}> units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator + /(IEnumerable<{typeNameA}?> units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator + /({typeNameZ} dividend, IEnumerable<{typeNameA}> units) => dividend._Value.Divide<{typeNameA}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator + /({typeNameZ} dividend, IEnumerable<{typeNameA}?> units) => dividend._Value.Divide<{typeNameA}, {typeNameB}>(units); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator /(IEnumerable<{typeNameA}> units, {typeNameZ}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => new {typeNameB}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator /(IEnumerable<{typeNameA}?> units, {typeNameZ}? divisor) => + divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameB}?)null : new {typeNameB}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator /({typeNameZ}? dividend, IEnumerable<{typeNameA}> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => new {typeNameB}(0d))); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator /({typeNameZ}? dividend, IEnumerable<{typeNameA}?> units) => + dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameB}?)null : new {typeNameB}(0d))); + } + + internal static class {typeNameZ}Extensions + { + public static double Protected(this {typeNameZ}? unit) => unit is null ? 0d : unit.Value._Value; + internal static double ToDouble(this {typeNameB}? unit) => unit?._Value ?? 0d; + } + + public class {typeNameZ}Converter : JsonConverter<{typeNameZ}> + { + // Используем инвариантную культуру, чтобы разделителем всегда была точка (10.5, а не 10,5) + private static readonly CultureInfo Culture = CultureInfo.InvariantCulture; + + public override {typeNameZ} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + double double_Value; + + if (reader.TokenType == JsonTokenType.String) + { + // Безопасно парсим double из строки с поддержкой точки как разделителя + if (!double.TryParse(reader.GetString(), NumberStyles.Float, Culture, out double_Value)) + { + throw new JsonException($""Не удалось преобразовать строковое значение в double для метрики {nameof({typeNameZ})}.""); + } + } + else + { + // Прямое быстрое чтение числа из JSON + double_Value = reader.GetDouble(); + } + + return new(double_Value); + } + + public override void Write(Utf8JsonWriter writer, {typeNameZ} value, JsonSerializerOptions options) + { + // Записываем число напрямую в байтовый буфер без выделения памяти под строки + writer.WriteNumberValue(value._Value); + } + + public override void WriteAsPropertyName(Utf8JsonWriter writer, {typeNameZ} value, JsonSerializerOptions options) + { + // Ключи JSON-объектов всегда должны быть строками. + // Форматируем double в строку с точкой, чтобы другие сервисы экосистемы прочитали её корректно. + // Формат ""R"" (Round-trip) гарантирует, что число не потеряет точность при обратном парсинге. + writer.WritePropertyName(value._Value.ToString(""R"", Culture)); + } + + public override {typeNameZ} ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + string propertyName = reader.GetString()!; + + if (!double.TryParse(propertyName, NumberStyles.Float, Culture, out double double_Value)) + { + throw new JsonException($""Невалидное числовое значение в ключе свойства JSON: '{propertyName}' для метрики {nameof({typeNameZ})}.""); + } + + return new(double_Value); + } + } +} +"; + + return template + .Replace("{ns}", ns) + .Replace("{typeName}", typeName) + .Replace("{typeNameA}", typeNameA) + .Replace("{typeNameB}", typeNameB) + .Replace("{typeNameZ}", typeNameZ); + } + + private readonly struct StructInfo(string ns, string name, string a, string b, string z) + { + public string Namespace { get; } = ns; + public string TypeName { get; } = name; + public string TypeNameA { get; } = a; + public string TypeNameB { get; } = b; + public string TypeNameZ { get; } = z; + } +} \ No newline at end of file diff --git a/QWERTYkez.Mensura.Generator/OperatorsGenerator.cs b/QWERTYkez.Mensura.Generator/OperatorsGenerator.cs index deb9f04..c70e77e 100644 --- a/QWERTYkez.Mensura.Generator/OperatorsGenerator.cs +++ b/QWERTYkez.Mensura.Generator/OperatorsGenerator.cs @@ -1,226 +1,195 @@ -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.CSharp.Syntax; -//using Microsoft.CodeAnalysis.Text; -//using System.Collections.Generic; -//using System.Collections.Immutable; -//using System.Linq; -//using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; +using System.Collections.Immutable; +using System.Linq; +using System.Text; -//namespace QWERTYkez.Mensura.Generator; +namespace G; -//[Generator(LanguageNames.CSharp)] -//internal class CollectionsOperatorsGenerator : IIncrementalGenerator -//{ -// private const string AttributeShortName = "CollectionsOperatorsGenerator"; -// private const string AttributeFullName = AttributeShortName + "Attribute"; +[Generator(LanguageNames.CSharp)] +public class CollectionsOperatorsGenerator : IIncrementalGenerator +{ + private const string AttributeShortName = "CollectionsOperatorsGenerator"; + 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)] -//internal sealed class CollectionsOperatorsGeneratorAttribute : System.Attribute { }"; +[System.AttributeUsage(System.AttributeTargets.Struct | System.AttributeTargets.Method, AllowMultiple = false, Inherited = false)] +internal sealed class CollectionsOperatorsGeneratorAttribute : System.Attribute { }"; -// public void Initialize(IncrementalGeneratorInitializationContext context) -// { -// context.RegisterPostInitializationOutput(context => -// context.AddSource( -// $"{AttributeFullName}.g", -// SourceText.From(AttributeSource, Encoding.UTF8))); + // Какие типы коллекций поддерживаем + private static readonly (string Type, string Selector)[] CollectionTypes = + [ + ("T[]", "array => array.Select(u => left * u).ToArray()"), // но нужно адаптировать под конкретный тип + // Проще генерировать отдельные методы для каждого типа + ]; -// var operatorsPipeline = -// context.SyntaxProvider.CreateSyntaxProvider>>( -// (node, _) => -// { -// if (node is ClassDeclarationSyntax cds) -// { -// SyntaxNode sn = cds; -// while (sn.Parent is not null && -// sn.Parent is not FileScopedNamespaceDeclarationSyntax) -// { -// sn = sn.Parent; -// } -// if (sn.Parent is FileScopedNamespaceDeclarationSyntax -// && cds.TypeParameterList is null -// && -// ((cds.Members.OfType() -// .Where(m => m.AttributeLists.SelectMany(al => al.Attributes) -// .Any(a => a.Name.GetText().ToString().Contains(AttributeShortName))) -// .Any()) -// || -// (cds.Modifiers.Any(m => m.Text == "partial") -// && cds.AttributeLists -// .SelectMany(al => al.Attributes) -// .Any(a => a.Name -// .GetText() -// .ToString() -// .Contains(AttributeShortName))))) -// { -// return true; -// } -// } -// return false; -// }, -// (syntax, _) => -// { -// string nameSpace; -// var cds = (ClassDeclarationSyntax)syntax.Node; -// { -// SyntaxNode sn = cds; -// while (sn.Parent is not FileScopedNamespaceDeclarationSyntax) -// { -// sn = sn.Parent!; -// } -// var nds = (FileScopedNamespaceDeclarationSyntax)sn.Parent; -// nameSpace = nds.Name.ToString(); -// } -// var Res = new StringBuilder(); -// { -// Res.Append(cds.Modifiers); -// Res.Append(" class "); -// Res.Append(cds.Identifier.Text); -// Res.Append(" "); -// Res.Append(cds.BaseList); -// Res.Append(" "); -// Res.Append(cds.ConstraintClauses); -// } + public void Initialize(IncrementalGeneratorInitializationContext context) + { + context.RegisterPostInitializationOutput(ctx => + ctx.AddSource($"{AttributeFullName}.g", SourceText.From(AttributeSource, Encoding.UTF8))); -// var operators = cds.Members.OfType() -// .Where(m => m.AttributeLists -// .SelectMany(al => al.Attributes) -// .Any(a => a.Name.GetText().ToString().Contains(AttributeShortName))) -// .Where(mb => mb.ParameterList.Parameters.Count == 2) -// .Select(mb => new Operation() -// { -// ReturnType = mb.ReturnType.ToString(), -// OperatorToken = mb.OperatorToken.Text, -// TypeA = mb.ParameterList.Parameters[0].Type!.ToString(), -// TypeB = mb.ParameterList.Parameters[1].Type!.ToString(), -// }); -// return new(new(nameSpace, cds.Identifier.Text, Res.ToString()), [.. operators]); -// }) -// .Collect(); + var operatorsPipeline = context.SyntaxProvider + .CreateSyntaxProvider( + predicate: static (node, _) => IsTargetType(node), + transform: static (ctx, _) => GetTypeInfo(ctx)) + .Where(info => info.HasValue) // использование nullable value type + .Select((info, _) => info!.Value) + .Collect(); -// context.RegisterSourceOutput(operatorsPipeline, GenerateOperators); -// } + context.RegisterSourceOutput(operatorsPipeline, GenerateOperators); + } -// readonly static string[] CollectionTypes = ["MetricArray", "MetricList", "MetricObservableCollection"]; -// static void GenerateOperators(SourceProductionContext context, ImmutableArray>> pairs) -// { -// foreach (var ng in pairs.GroupBy(c => c.Key.NameSpace)) -// { -// StringBuilder document = new("namespace "); -// document.Append(ng.Key); -// document.Append(";"); + private static bool IsTargetType(SyntaxNode node) + { + if (node is not TypeDeclarationSyntax typeDecl) + return false; -// var classes = ng.ToList().Select(c => (ClassData?)c.Key).ToList(); -// var operations = ng.ToList().SelectMany(c => c.Value).ToList(); -// var multiplications = operations.Where(op => op.OperatorToken == "*").ToList(); -// var divisions = operations.Where(op => op.OperatorToken == "/").ToList(); + // Должен быть partial и не generic + if (!typeDecl.Modifiers.Any(SyntaxKind.PartialKeyword)) + return false; + if (typeDecl.TypeParameterList != null) + return false; -// foreach (var ops in multiplications.GroupBy(op => op.TypeA)) -// { -// var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key); -// if (Class is not null) -// { -// document.AppendLine(); -// document.AppendLine(); -// document.AppendLine(Class.Value.ClassHeader); -// document.AppendLine("{"); -// foreach (var op in ops) -// foreach (var ct in CollectionTypes) -// { -// 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 *({ct}<{op.TypeB}> left, {op.TypeA} right) => left.MetricSelect(UU => UU * right); -//"); -// } -// document.Append("}"); -// } -// else -// { -// context.ReportDiagnostic(Diagnostic.Create(new( -// "MSG0001", -// "Need a class with an attribute", -// $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"", -// "category", -// DiagnosticSeverity.Error, -// true), null, ops.Key)); -// } -// } + // Проверяем наличие атрибута на самом типе + foreach (var attrList in typeDecl.AttributeLists) + foreach (var attr in attrList.Attributes) + { + string name = attr.Name.ToString(); + if (name == AttributeShortName || name == AttributeFullName) + return true; + } -// foreach (var ops in divisions.GroupBy(op => op.TypeA)) -// { -// var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key); -// if (Class is not null) -// { -// document.AppendLine(); -// document.AppendLine(); -// document.AppendLine(Class.Value.ClassHeader); -// document.AppendLine("{"); -// foreach (var op in ops) -// foreach (var ct in CollectionTypes) -// { -// document.AppendLine(@$" -// public static {ct}<{op.ReturnType}> operator /({op.TypeA} left, {ct}<{op.TypeB}> right) => right.MetricSelect(UU => left / UU); -//"); -// } -// document.Append("}"); -// } -// else -// { -// context.ReportDiagnostic(Diagnostic.Create(new( -// "MSG0001", -// "Need a class with an attribute", -// $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"", -// "category", -// DiagnosticSeverity.Error, -// true), null, ops.Key)); -// } -// } -// foreach (var ops in divisions.GroupBy(op => op.TypeB)) -// { -// var Class = classes.FirstOrDefault(cl => cl!.Value.ClassName == ops.Key); -// if (Class is not null) -// { -// document.AppendLine(); -// document.AppendLine(); -// document.AppendLine(Class.Value.ClassHeader); -// document.AppendLine("{"); -// foreach (var op in ops) -// foreach (var ct in CollectionTypes) -// { -// document.AppendLine(@$" -// public static {ct}<{op.ReturnType}> operator /({ct}<{op.TypeA}> left, {op.TypeB} right) => left.MetricSelect(UU => UU / right); -//"); -// } -// document.Append("}"); -// } -// else -// { -// context.ReportDiagnostic(Diagnostic.Create(new( -// "MSG0001", -// "Need a class with an attribute", -// $"It is necessary to have a empty partial class \"{ops.Key}\" with the attribute \"{AttributeShortName}\"", -// "category", -// DiagnosticSeverity.Error, -// true), null, ops.Key)); -// } -// } + // Или на операторах внутри + foreach (var member in typeDecl.Members) + { + if (member is OperatorDeclarationSyntax opDecl && + opDecl.AttributeLists.SelectMany(al => al.Attributes) + .Any(a => a.Name.ToString().Contains(AttributeShortName))) + return true; + } + return false; + } -// context.AddSource($"operations.{ng.Key}.g", document.ToString()); -// } -// } -//} + private static TypeInfoData? GetTypeInfo(GeneratorSyntaxContext ctx) + { + var typeDecl = (TypeDeclarationSyntax)ctx.Node; + var semanticModel = ctx.SemanticModel; -//public struct ClassData(string nameSpace, string className, string classHeader) -//{ -// public string NameSpace = nameSpace; -// public string ClassName = className; -// public string ClassHeader = classHeader; -//} -//public struct Operation(string operatorToken, string typeA, string typeB, string returnType) -//{ -// public string ReturnType = returnType; -// public string OperatorToken = operatorToken; -// public string TypeA = typeA; -// public string TypeB = typeB; -//} \ No newline at end of file + var symbol = semanticModel.GetDeclaredSymbol(typeDecl); + if (symbol == null) return null; + + string namespaceName = symbol.ContainingNamespace?.ToString() ?? ""; + + // Формируем заголовок (для отладочных целей) + var headerBuilder = new StringBuilder(); + foreach (var modifier in typeDecl.Modifiers) + headerBuilder.Append(modifier.Text).Append(' '); + if (typeDecl is RecordDeclarationSyntax) + headerBuilder.Append("record "); + headerBuilder.Append(typeDecl.Identifier.Text); + string header = headerBuilder.ToString(); + + // Собираем операторы + var operators = ImmutableArray.CreateBuilder(); + foreach (var member in typeDecl.Members) + { + if (member is not OperatorDeclarationSyntax opDecl) continue; + if (opDecl.ParameterList.Parameters.Count != 2) continue; + if (!opDecl.AttributeLists.SelectMany(al => al.Attributes) + .Any(a => a.Name.ToString().Contains(AttributeShortName))) continue; + + operators.Add(new Operation( + opDecl.OperatorToken.Text, + opDecl.ParameterList.Parameters[0].Type!.ToString(), + opDecl.ParameterList.Parameters[1].Type!.ToString(), + opDecl.ReturnType.ToString() + )); + } + + if (operators.Count == 0) return null; + + return new TypeInfoData(namespaceName, typeDecl.Identifier.Text, header, operators.ToImmutable()); + } + + private static void GenerateOperators(SourceProductionContext context, ImmutableArray types) + { + foreach (var group in types.GroupBy(t => t.Namespace)) + { + var document = new StringBuilder(); + document.AppendLine("namespace ").Append(group.Key).AppendLine(";"); + document.AppendLine("using System.Collections.Generic;"); + document.AppendLine("using System.Linq;"); + + var allOperators = group.SelectMany(t => t.Operators).ToList(); + var multiplications = allOperators.Where(op => op.OperatorToken == "*").ToList(); + var divisions = allOperators.Where(op => op.OperatorToken == "/").ToList(); + + // Генерация для умножения: left * collection и collection * left + foreach (var mul in multiplications) + { + // left * collection + document.AppendLine($@" + public static {mul.ReturnType}[] operator *({mul.TypeA} left, {mul.TypeB}[] right) => + right.Select(u => left * u).ToArray(); + public static List<{mul.ReturnType}> operator *({mul.TypeA} left, List<{mul.TypeB}> right) => + right.Select(u => left * u).ToList(); + public static IEnumerable<{mul.ReturnType}> operator *({mul.TypeA} left, IEnumerable<{mul.TypeB}> right) => + right.Select(u => left * u); +"); + // collection * left + document.AppendLine($@" + public static {mul.ReturnType}[] operator *({mul.TypeB}[] left, {mul.TypeA} right) => + left.Select(u => u * right).ToArray(); + public static List<{mul.ReturnType}> operator *(List<{mul.TypeB}> left, {mul.TypeA} right) => + left.Select(u => u * right).ToList(); + public static IEnumerable<{mul.ReturnType}> operator *(IEnumerable<{mul.TypeB}> left, {mul.TypeA} right) => + left.Select(u => u * right); +"); + } + + // Деление: left / collection (left - тип A, collection - тип B) + foreach (var div in divisions.Where(op => op.TypeA != null)) // все деления + { + // left / collection + document.AppendLine($@" + public static {div.ReturnType}[] operator /({div.TypeA} left, {div.TypeB}[] right) => + right.Select(u => left / u).ToArray(); + public static List<{div.ReturnType}> operator /({div.TypeA} left, List<{div.TypeB}> right) => + right.Select(u => left / u).ToList(); + public static IEnumerable<{div.ReturnType}> operator /({div.TypeA} left, IEnumerable<{div.TypeB}> right) => + right.Select(u => left / u); +"); + // collection / right (где right - тип B) + document.AppendLine($@" + public static {div.ReturnType}[] operator /({div.TypeA}[] left, {div.TypeB} right) => + left.Select(u => u / right).ToArray(); + public static List<{div.ReturnType}> operator /(List<{div.TypeA}> left, {div.TypeB} right) => + left.Select(u => u / right).ToList(); + public static IEnumerable<{div.ReturnType}> operator /(IEnumerable<{div.TypeA}> left, {div.TypeB} right) => + left.Select(u => u / right); +"); + } + + context.AddSource($"operations.{group.Key}.g", document.ToString()); + } + } + + private readonly struct TypeInfoData(string ns, string name, string header, ImmutableArray ops) + { + public string Namespace { get; } = ns; + public string TypeName { get; } = name; + public string Header { get; } = header; + public ImmutableArray Operators { get; } = ops; + } + + private readonly struct Operation(string token, string a, string b, string ret) + { + public string OperatorToken { get; } = token; + public string TypeA { get; } = a; + public string TypeB { get; } = b; + public string ReturnType { get; } = ret; + } +} \ No newline at end of file diff --git a/QWERTYkez.Mensura.Generator/QWERTYkez.Mensura.Generator.csproj b/QWERTYkez.Mensura.Generator/QWERTYkez.Mensura.Generator.csproj index c59ec9c..1cf68a9 100644 --- a/QWERTYkez.Mensura.Generator/QWERTYkez.Mensura.Generator.csproj +++ b/QWERTYkez.Mensura.Generator/QWERTYkez.Mensura.Generator.csproj @@ -4,14 +4,7 @@ netstandard2.0 latest true - - - - 1701;1702;IDE0079;MVVMTK0034 - - - - 1701;1702;IDE0079;MVVMTK0034 + 1701;1702;IDE0079;MVVMTK0034;IDE0130 diff --git a/QWERTYkez.Mensura.Generator/UnitOperatorsGenerator.cs b/QWERTYkez.Mensura.Generator/UnitGenerator.cs similarity index 96% rename from QWERTYkez.Mensura.Generator/UnitOperatorsGenerator.cs rename to QWERTYkez.Mensura.Generator/UnitGenerator.cs index 2bcdaa9..5d115ef 100644 --- a/QWERTYkez.Mensura.Generator/UnitOperatorsGenerator.cs +++ b/QWERTYkez.Mensura.Generator/UnitGenerator.cs @@ -4,12 +4,12 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System.Text; -namespace QWERTYkez.Mensura.Generator; +namespace G; [Generator] -public class UnitOperatorsGenerator : IIncrementalGenerator +public class UnitGenerator : IIncrementalGenerator { - private const string AttributeName = "UnitOperatorsGenerator"; + private const string AttributeName = "UnitGenerator"; public void Initialize(IncrementalGeneratorInitializationContext context) { @@ -20,9 +20,9 @@ public class UnitOperatorsGenerator : IIncrementalGenerator namespace QWERTYkez.Mensura { [System.AttributeUsage(System.AttributeTargets.Struct, AllowMultiple = false)] - public sealed class UnitOperatorsGeneratorAttribute : System.Attribute { } + public sealed class UnitGeneratorAttribute : System.Attribute { } }"; - ctx.AddSource("UnitOperatorsGeneratorAttribute.g.cs", SourceText.From(attributeSource, Encoding.UTF8)); + ctx.AddSource(".UnitGeneratorAttribute.g.cs", SourceText.From(attributeSource, Encoding.UTF8)); }); // Ищем все readonly partial record struct с атрибутом @@ -39,7 +39,7 @@ namespace QWERTYkez.Mensura foreach (var structInfo in structs) { string generatedCode = GeneratePartial(structInfo); - spc.AddSource($"{structInfo.TypeName}.Generated.g.cs", SourceText.From(generatedCode, Encoding.UTF8)); + spc.AddSource($"{structInfo.TypeName}.g.cs", SourceText.From(generatedCode, Encoding.UTF8)); } }); } @@ -56,7 +56,7 @@ namespace QWERTYkez.Mensura !record.ClassOrStructKeyword.IsKind(SyntaxKind.StructKeyword)) return false; - // Проверяем наличие атрибута [UnitOperatorsGenerator] + // Проверяем наличие атрибута [UnitGenerator] foreach (var attrList in record.AttributeLists) foreach (var attr in attrList.Attributes) { diff --git a/QWERTYkez.Mensura/Operators.cs b/QWERTYkez.Mensura/Operators.cs index 2656402..7dfbf60 100644 --- a/QWERTYkez.Mensura/Operators.cs +++ b/QWERTYkez.Mensura/Operators.cs @@ -1,231 +1,216 @@ -//namespace QWERTYkez.Mensura.Units; +namespace QWERTYkez.Mensura.Units; -//internal static class OperationsExtension +internal static class OperationsExtension +{ + internal static TResult MultiplyProtected(this T1 t1, T2 t2) + where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit + => (t1.ToDouble() * t2.ToDouble()).ToUnit(); + + internal static TResult MultiplyProtected(this T1 t1, T2 t2, double multiplicator) + where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit + => (t1.ToDouble() * t2.ToDouble() * multiplicator).ToUnit(); + + internal static TResult DivideProtected(this T1 t1, T2 t2) + where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit + => (t1.ToDouble() / t2.ToDouble()).ToUnit(); + + internal static TResult DivideProtected(this T1 t1, T2 t2, double multiplicator) + where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit + => (t1.ToDouble() * multiplicator / t2.ToDouble()).ToUnit(); +} + +internal static class Coefficients +{ + internal static double MultiplyCoefficient(T1 a, T2 b, TResult r) + where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit + => r.ToDouble() / (a.ToDouble() * b.ToDouble()); + + internal static double DivideCoefficient(T1 a, T2 b, TResult r) + where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit + where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit + => r.ToDouble() * b.ToDouble() / a.ToDouble(); +} + + + + +[CollectionsOperatorsGenerator] public readonly partial record struct Length +{ + [CollectionsOperatorsGenerator] public static Area operator *(Length left, Length right) + => left.MultiplyProtected(right, Coeff1); + + static readonly double Coeff1 = Coefficients.MultiplyCoefficient(MilliMeter, MilliMeter, Area.MilliMeterSquared); + + + [CollectionsOperatorsGenerator] public static Volume operator *(Area left, Length right) => right * left; + [CollectionsOperatorsGenerator] public static Volume operator *(Length left, Area right) + => left.MultiplyProtected(right, Coeff2); + + static readonly double Coeff2 = Coefficients.MultiplyCoefficient(MilliMeter, Area.MilliMeterSquared, Volume.MilliMeterCubic); + + + [CollectionsOperatorsGenerator] public static Pressure operator *(Length left, ForceVolumetric right) => right * left; + [CollectionsOperatorsGenerator] public static Pressure operator *(ForceVolumetric left, Length right) => left.MultiplyProtected(right, Coeff3); + static readonly double Coeff3 = Coefficients.MultiplyCoefficient(ForceVolumetric.NewtonPerMeterCubic, Length.Meter, Pressure.NewtonPerMeterSquared); + + + [CollectionsOperatorsGenerator] public static Torque operator *(Force left, Length right) => right * left; + [CollectionsOperatorsGenerator] public static Torque operator *(Length left, Force right) => left.MultiplyProtected(right, Coeff6); + static readonly double Coeff6 = Coefficients.MultiplyCoefficient(Length.Meter, Force.Newton, Torque.Newton_Meter); +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Mass // Grams +{ + +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Pressure // Pascals +{ + [CollectionsOperatorsGenerator] public static Length operator /(Pressure left, ForceVolumetric right) => left.DivideProtected(right, Coeff1); + static readonly double Coeff1 = Coefficients.DivideCoefficient(Pressure.Pascal, ForceVolumetric.NewtonPerMeterCubic, Length.Meter); + + [CollectionsOperatorsGenerator] public static Force operator *(Pressure left, Area right) => right * left; + [CollectionsOperatorsGenerator] public static Force operator *(Area left, Pressure right) => left.MultiplyProtected(right, Coeff2); + static readonly double Coeff2 = Coefficients.MultiplyCoefficient(Area.MeterSquared, Pressure.Pascal, Force.Newton); + + + + [CollectionsOperatorsGenerator] public static Length operator /(ForceLinear left, Pressure right) => left.DivideProtected(right, Coeff3); + static readonly double Coeff3 = Coefficients.DivideCoefficient(ForceLinear._NewtonPerMilliMeter, Pressure.NewtonPerMilliMeterSquared, Length.MilliMeter); + + [CollectionsOperatorsGenerator] public static ForceLinear operator *(Pressure left, Length right) => right * left; + [CollectionsOperatorsGenerator] public static ForceLinear operator *(Length left, Pressure right) => left.MultiplyProtected(right, Coeff4); + static readonly double Coeff4 = Coefficients.MultiplyCoefficient(Length.MilliMeter, Pressure.NewtonPerMilliMeterSquared, ForceLinear._NewtonPerMilliMeter); +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Area // MilliMetersSquared +{ + [CollectionsOperatorsGenerator] public static Torque operator *(ForceLinear left, Area right) => right * left; + [CollectionsOperatorsGenerator] public static Torque operator *(Area left, ForceLinear right) => left.MultiplyProtected(right, Coeff1); + static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Area.MeterSquared, ForceLinear.NewtonPerMeter, Torque.Newton_Meter); + + [CollectionsOperatorsGenerator] public static Length operator /(Area left, Length right) => left.DivideProtected(right, Coeff2); + static readonly double Coeff2 = Coefficients.DivideCoefficient(Area.MilliMeterSquared, Length.MilliMeter, Length.MilliMeter); +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Volume // MillimetersCubic +{ + [CollectionsOperatorsGenerator] public static Torque operator *(Pressure left, Volume right) => right * left; + [CollectionsOperatorsGenerator] public static Torque operator *(Volume left, Pressure right) => left.MultiplyProtected(right, Coeff2); + static readonly double Coeff2 = Coefficients.MultiplyCoefficient(Volume.MeterCubic, Pressure.Pascal, Torque.Newton_Meter); + + [CollectionsOperatorsGenerator] public static Area operator /(Volume left, Length right) => left.DivideProtected(right); + [CollectionsOperatorsGenerator] public static Length operator /(Volume left, Area right) => left.DivideProtected(right, Coeff3); + static readonly double Coeff3 = Coefficients.DivideCoefficient(Volume.MilliMeterCubic, Length.MilliMeter, Area.MilliMeterSquared); +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Force // Newtons +{ + [CollectionsOperatorsGenerator] public static Area operator /(Force left, Pressure right) => left.DivideProtected(right, Coeff1); + static readonly double Coeff1 = Coefficients.DivideCoefficient(Force.Newton, Pressure.Pascal, Area.MeterSquared); + [CollectionsOperatorsGenerator] public static Pressure operator /(Force left, Area right) => left.DivideProtected(right, Coeff2); + static readonly double Coeff2 = Coefficients.DivideCoefficient(Force.Newton, Area.MeterSquared, Pressure.Pascal); + +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Torque // NewtonMeters +{ + [CollectionsOperatorsGenerator] public static Length operator /(Torque left, Force right) => left.DivideProtected(right, Coeff1); + static readonly double Coeff1 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Force.Newton, Length.Meter); + [CollectionsOperatorsGenerator] public static Force operator /(Torque left, Length right) => left.DivideProtected(right, Coeff2); + static readonly double Coeff2 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Length.Meter, Force.Newton); + [CollectionsOperatorsGenerator] public static ForceLinear operator /(Torque left, Area right) => left.DivideProtected(right, Coeff3); + static readonly double Coeff3 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Area.MilliMeterSquared, ForceLinear.KiloNewtonPerMilliMeter ); + [CollectionsOperatorsGenerator] public static Pressure operator /(Torque left, Volume right) => left.DivideProtected(right, Coeff4); + static readonly double Coeff4 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Volume.MeterCubic, Pressure.Pascal); + [CollectionsOperatorsGenerator] public static Volume operator /(Torque left, Pressure right) => left.DivideProtected(right, Coeff5); + static readonly double Coeff5 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Pressure.Pascal, Volume.MeterCubic); +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Frequency // Hertz +{ + +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Time +{ + [CollectionsOperatorsGenerator] public static Speed operator *(Boost left, Time right) => right * left; + [CollectionsOperatorsGenerator] public static Speed operator *(Time left, Boost right) => left.MultiplyProtected(right, Coeff1); + static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Time.Second, Boost.MeterPerSecondSquared, Speed.MeterPerSecond); + + [CollectionsOperatorsGenerator] public static Speed operator /(Length left, Time right) => left.DivideProtected(right, Coeff2); + static readonly double Coeff2 = Coefficients.DivideCoefficient(Length.Meter, Time.Second, Speed.MeterPerSecond); +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Speed +{ + [CollectionsOperatorsGenerator] public static Length operator *(Speed left, Time right) => right * left; + [CollectionsOperatorsGenerator] public static Length operator *(Time left, Speed right) => left.MultiplyProtected(right, Coeff1); + static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Time.Second, Speed.MeterPerSecond, Length.Meter); + + [CollectionsOperatorsGenerator] public static Boost operator /(Speed left, Time right) => left.DivideProtected(right, Coeff2); + static readonly double Coeff2 = Coefficients.DivideCoefficient(Speed.MeterPerSecond, Time.Second, Boost.MeterPerSecondSquared); +} + +[CollectionsOperatorsGenerator] public readonly partial record struct Boost +{ + [CollectionsOperatorsGenerator] public static Force operator *(Mass left, Boost right) => right * left; + [CollectionsOperatorsGenerator] public static Force operator *(Boost left, Mass right) => left.MultiplyProtected(right, Coeff1); + static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Boost.MeterPerSecondSquared, Mass.KiloGram, Force.Newton); + + [CollectionsOperatorsGenerator] public static ForceLinear operator *(MassLinear left, Boost right) => right * left; + [CollectionsOperatorsGenerator] public static ForceLinear operator *(Boost left, MassLinear right) => left.MultiplyProtected(right, Coeff2); + static readonly double Coeff2 = Coefficients.MultiplyCoefficient(Boost.MeterPerSecondSquared, MassLinear.KiloGramPerMilliMeter, ForceLinear._NewtonPerMilliMeter); + + [CollectionsOperatorsGenerator] public static ForceVolumetric operator *(Density left, Boost right) => right * left; + [CollectionsOperatorsGenerator] public static ForceVolumetric operator *(Boost left, Density right) => left.MultiplyProtected(right, Coeff3); + static readonly double Coeff3 = Coefficients.MultiplyCoefficient(Boost.MeterPerSecondSquared, Density.KiloGramPerMilliMeterCubic, ForceVolumetric._NewtonPerMilliMeterCubic); + + + [CollectionsOperatorsGenerator] public static MassLinear operator /(ForceLinear left, Boost right) => left.DivideProtected(right, Coeff4); + static readonly double Coeff4 = Coefficients.DivideCoefficient(ForceLinear._NewtonPerMilliMeter, Boost.MeterPerSecondSquared, MassLinear.KiloGramPerMilliMeter); + + [CollectionsOperatorsGenerator] public static Density operator /(ForceVolumetric left, Boost right) => left.DivideProtected(right, Coeff5); + static readonly double Coeff5 = Coefficients.DivideCoefficient(ForceVolumetric._NewtonPerMilliMeterCubic, Boost.MeterPerSecondSquared, Density.KiloGramPerMilliMeterCubic); + + + [CollectionsOperatorsGenerator] public static MassPerSquare operator /(Pressure left, Boost right) => left.DivideProtected(right, Coeff6); + static readonly double Coeff6 = Coefficients.DivideCoefficient(Pressure.Pascal, Boost.MeterPerSecondSquared, MassPerSquare.KiloGramPerMeterSquared); +} + +[CollectionsOperatorsGenerator] public readonly partial record struct MassPerSquare +{ + [CollectionsOperatorsGenerator] public static Pressure operator *(Boost left, MassPerSquare right) => right * left; + [CollectionsOperatorsGenerator] public static Pressure operator *(MassPerSquare left, Boost right) => left.MultiplyProtected(right, Coeff1); + static readonly double Coeff1 = Coefficients.MultiplyCoefficient(MassPerSquare.KiloGramPerMeterSquared, Boost.MeterPerSecondSquared, Pressure.Pascal); +} + +//[CollectionsOperatorsGenerator] public readonly partial record struct LinearForce : Pogon //{ -// internal static TResult MultiplyProtected(this T1 t1, T2 t2) -// where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit -// => new() { Value = t1.Value * t2.Value }; -// internal static TResult MultiplyProtected(this T1 t1, T2 t2, double multiplicator) -// where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit -// => new() { Value = t1.Value * t2.Value * multiplicator }; - -// internal static TResult DivideProtected(this T1 t1, T2 t2) -// where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit -// => new() { Value = t1.Value / t2.Value }; - -// internal static TResult DivideProtected(this T1 t1, T2 t2, double multiplicator) -// where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit -// => new() { Value = t1.Value * multiplicator / t2.Value }; -//} - -//internal static class Coefficients -//{ -// internal static double MultiplyCoefficient(T1 a, T2 b, TResult r) -// where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit -// => r.Value / (a.Value * b.Value); - -// internal static double DivideCoefficient(T1 a, T2 b, TResult r) -// where T1 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where T2 : struct, IMensuraUnit, IEquatable, IMensuraUnit -// where TResult : struct, IMensuraUnit, IEquatable, IMensuraUnit -// => r.Value * b.Value / a.Value; -//} - - - - -//[CollectionsOperatorsGenerator] public readonly partial record struct Length -//{ -// [CollectionsOperatorsGenerator] public static Area operator *(Length left, Length right) -// => left.MultiplyProtected(right, Coeff1); - -// static readonly double Coeff1 = Coefficients.MultiplyCoefficient(MilliMeter, MilliMeter, Area.MilliMeterSquared); - - -// [CollectionsOperatorsGenerator] public static Volume operator *(Area left, Length right) => right * left; -// [CollectionsOperatorsGenerator] public static Volume operator *(Length left, Area right) -// => left.MultiplyProtected(right, Coeff2); - -// static readonly double Coeff2 = Coefficients.MultiplyCoefficient(MilliMeter, Area.MilliMeterSquared, Volume.MilliMeterCubic); - - -// [CollectionsOperatorsGenerator] public static Pressure operator *(Length left, UdelForce right) => right * left; -// [CollectionsOperatorsGenerator] public static Pressure operator *(UdelForce left, Length right) => left.MultiplyProtected(right, Coeff3); -// static readonly double Coeff3 = Coefficients.MultiplyCoefficient(a => a.PerMeterCubic.Newtons = 1, Length.Meter, Pressure.NewtonPerMeterSquared); - - -// [CollectionsOperatorsGenerator] public static Force operator *(PogonForce left, Length right) => right * left; -// [CollectionsOperatorsGenerator] public static Force operator *(Length left, PogonForce right) => left.MultiplyProtected(right, Coeff4); -// static readonly double Coeff4 = Coefficients.MultiplyCoefficient(Length.Meter, b => b.PerMeter.Newtons = 1, Force.Newton); - - -// [CollectionsOperatorsGenerator] public static Torque operator *(Force left, Length right) => right * left; -// [CollectionsOperatorsGenerator] public static Torque operator *(Length left, Force right) => left.MultiplyProtected(right, Coeff6); -// static readonly double Coeff6 = Coefficients.MultiplyCoefficient(Length.Meter, Force.Newton, Torque.Newton_Meter); -//} - -//[CollectionsOperatorsGenerator] public readonly partial record struct Mass // Grams -//{ //} -//[CollectionsOperatorsGenerator] public readonly partial record struct Pressure // Pascals +//[CollectionsOperatorsGenerator] public readonly partial record struct MassLinear : Pogon //{ -// [CollectionsOperatorsGenerator] public static Length operator /(Pressure left, UdelForce right) => left.DivideProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.DivideCoefficient(Pressure.Pascal, b => b.PerMeterCubic.Newtons = 1, Length.Meter); +// [CollectionsOperatorsGenerator] public static Boost operator /(LinearForce left, MassLinear right) => left.DivideProtected(right, Coeff1); -// [CollectionsOperatorsGenerator] public static Force operator *(Pressure left, Area right) => right * left; -// [CollectionsOperatorsGenerator] public static Force operator *(Area left, Pressure right) => left.MultiplyProtected(right, Coeff2); -// static readonly double Coeff2 = Coefficients.MultiplyCoefficient(Area.MeterSquared, Pressure.Pascal, Force.Newton); - - - -// [CollectionsOperatorsGenerator] public static Length operator /(PogonForce left, Pressure right) => left.DivideProtected(right, Coeff3); -// static readonly double Coeff3 = Coefficients.DivideCoefficient(a => a._PerMilliMeter.Newtons = 1, Pressure.NewtonPerMilliMeterSquared, Length.MilliMeter); - -// [CollectionsOperatorsGenerator] public static PogonForce operator *(Pressure left, Length right) => right * left; -// [CollectionsOperatorsGenerator] public static PogonForce operator *(Length left, Pressure right) => left.MultiplyProtected(right, Coeff4); -// static readonly double Coeff4 = Coefficients.MultiplyCoefficient(Length.MilliMeter, Pressure.NewtonPerMilliMeterSquared, r => r._PerMilliMeter.Newtons = 1); +// static readonly double Coeff1 = Coefficients.DivideCoefficient(a => a.PerMilliMeter.Newtons = 1, b => b.PerMilliMeter.KiloGrams = 1, Boost.MeterPerSecondSquared); //} -//[CollectionsOperatorsGenerator] public readonly partial record struct Area // MilliMetersSquared -//{ -// [CollectionsOperatorsGenerator] public static Torque operator *(PogonForce left, Area right) => right * left; -// [CollectionsOperatorsGenerator] public static Torque operator *(Area left, PogonForce right) => left.MultiplyProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Area.MeterSquared, b => b.PerMeter.Newtons = 1, Torque.Newton_Meter); - -// [CollectionsOperatorsGenerator] public static Length operator /(Area left, Length right) => left.DivideProtected(right, Coeff2); -// static readonly double Coeff2 = Coefficients.DivideCoefficient(Area.MilliMeterSquared, Length.MilliMeter, Length.MilliMeter); -//} - -//[CollectionsOperatorsGenerator] public readonly partial record struct Volume // MillimetersCubic -//{ -// [CollectionsOperatorsGenerator] public static Mass operator *(Density left, Volume right) => right * left; -// [CollectionsOperatorsGenerator] public static Mass operator *(Volume left, Density right) => left.MultiplyProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Volume.MilliMeterCubic, b => b.PerMilliMeterCubic.Grams = 1, Time.Gram); - -// [CollectionsOperatorsGenerator] public static Torque operator *(Pressure left, Volume right) => right * left; -// [CollectionsOperatorsGenerator] public static Torque operator *(Volume left, Pressure right) => left.MultiplyProtected(right, Coeff2); -// static readonly double Coeff2 = Coefficients.MultiplyCoefficient(Volume.MeterCubic, Pressure.Pascal, Torque.Newton_Meter); - -// [CollectionsOperatorsGenerator] public static Area operator /(Volume left, Length right) => left.DivideProtected(right); -// [CollectionsOperatorsGenerator] public static Length operator /(Volume left, Area right) => left.DivideProtected(right, Coeff3); -// static readonly double Coeff3 = Coefficients.DivideCoefficient(Volume.MilliMeterCubic, Length.MilliMeter, Area.MilliMeterSquared); -//} - -//[CollectionsOperatorsGenerator] public readonly partial record struct Force // Newtons -//{ -// [CollectionsOperatorsGenerator] public static Area operator /(Force left, Pressure right) => left.DivideProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.DivideCoefficient(Force.Newton, Pressure.Pascal, Area.MeterSquared); -// [CollectionsOperatorsGenerator] public static Pressure operator /(Force left, Area right) => left.DivideProtected(right, Coeff2); -// static readonly double Coeff2 = Coefficients.DivideCoefficient(Force.Newton, Area.MeterSquared, Pressure.Pascal); - -//} - -//[CollectionsOperatorsGenerator] public readonly partial record struct Torque // NewtonMeters -//{ -// [CollectionsOperatorsGenerator] public static Length operator /(Torque left, Force right) => left.DivideProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Force.Newton, Length.Meter); -// [CollectionsOperatorsGenerator] public static Force operator /(Torque left, Length right) => left.DivideProtected(right, Coeff2); -// static readonly double Coeff2 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Length.Meter, Force.Newton); -// [CollectionsOperatorsGenerator] public static PogonForce operator /(Torque left, Area right) => left.DivideProtected(right, Coeff3); -// static readonly double Coeff3 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Area.MilliMeterSquared, r => r.PerMilliMeter.KiloNewtons = 1); -// [CollectionsOperatorsGenerator] public static Pressure operator /(Torque left, Volume right) => left.DivideProtected(right, Coeff4); -// static readonly double Coeff4 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Volume.MeterCubic, Pressure.Pascal); -// [CollectionsOperatorsGenerator] public static Volume operator /(Torque left, Pressure right) => left.DivideProtected(right, Coeff5); -// static readonly double Coeff5 = Coefficients.DivideCoefficient(Torque.Newton_Meter, Pressure.Pascal, Volume.MeterCubic); -//} - -//[CollectionsOperatorsGenerator] public readonly partial record struct Frequency // Hertz +//[CollectionsOperatorsGenerator] public readonly partial record struct ForceVolumetric : Udel //{ -//} -//[CollectionsOperatorsGenerator] public readonly partial record struct Time -//{ -// [CollectionsOperatorsGenerator] public static Speed operator *(Boost left, Time right) => right * left; -// [CollectionsOperatorsGenerator] public static Speed operator *(Time left, Boost right) => left.MultiplyProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Time.Second, Boost.MeterPerSecondSquared, Speed.MeterPerSecond); - -// [CollectionsOperatorsGenerator] public static Speed operator /(Length left, Time right) => left.DivideProtected(right, Coeff2); -// static readonly double Coeff2 = Coefficients.DivideCoefficient(Length.Meter, Time.Second, Speed.MeterPerSecond); -//} - -//[CollectionsOperatorsGenerator] public readonly partial record struct Speed -//{ -// [CollectionsOperatorsGenerator] public static Length operator *(Speed left, Time right) => right * left; -// [CollectionsOperatorsGenerator] public static Length operator *(Time left, Speed right) => left.MultiplyProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Time.Second, Speed.MeterPerSecond, Length.Meter); - -// [CollectionsOperatorsGenerator] public static Boost operator /(Speed left, Time right) => left.DivideProtected(right, Coeff2); -// static readonly double Coeff2 = Coefficients.DivideCoefficient(Speed.MeterPerSecond, Time.Second, Boost.MeterPerSecondSquared); -//} - -//[CollectionsOperatorsGenerator] public readonly partial record struct Boost -//{ -// [CollectionsOperatorsGenerator] public static Force operator *(Mass left, Boost right) => right * left; -// [CollectionsOperatorsGenerator] public static Force operator *(Boost left, Mass right) => left.MultiplyProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.MultiplyCoefficient(Boost.MeterPerSecondSquared, Time.KiloGram, Force.Newton); - -// [CollectionsOperatorsGenerator] public static PogonForce operator *(PogonMass left, Boost right) => right * left; -// [CollectionsOperatorsGenerator] public static PogonForce operator *(Boost left, PogonMass right) => left.MultiplyProtected(right, Coeff2); -// static readonly double Coeff2 = Coefficients.MultiplyCoefficient(Boost.MeterPerSecondSquared, b => b.PerMilliMeter.KiloGrams = 1, r => r.PerMilliMeter.Newtons = 1); - -// [CollectionsOperatorsGenerator] public static UdelForce operator *(Density left, Boost right) => right * left; -// [CollectionsOperatorsGenerator] public static UdelForce operator *(Boost left, Density right) => left.MultiplyProtected(right, Coeff3); -// static readonly double Coeff3 = Coefficients.MultiplyCoefficient(Boost.MeterPerSecondSquared, b => b.PerMilliMeterCubic.KiloGrams = 1, r => r.PerMilliMeterCubic.Newtons = 1); - - -// [CollectionsOperatorsGenerator] public static PogonMass operator /(PogonForce left, Boost right) => left.DivideProtected(right, Coeff4); -// static readonly double Coeff4 = Coefficients.DivideCoefficient(a => a.PerMilliMeter.Newtons = 1, Boost.MeterPerSecondSquared, r => r.PerMilliMeter.KiloGrams = 1); - -// [CollectionsOperatorsGenerator] public static Density operator /(UdelForce left, Boost right) => left.DivideProtected(right, Coeff5); -// static readonly double Coeff5 = Coefficients.DivideCoefficient(a => a.PerMilliMeterCubic.Newtons = 1, Boost.MeterPerSecondSquared, r => r.PerMilliMeterCubic.KiloGrams = 1); - - -// [CollectionsOperatorsGenerator] public static MassPerSquare operator /(Pressure left, Boost right) => left.DivideProtected(right, Coeff6); -// static readonly double Coeff6 = Coefficients.DivideCoefficient(Pressure.Pascal, Boost.MeterPerSecondSquared, MassPerSquare.KiloGramPerMeterSquared); -//} - -//[CollectionsOperatorsGenerator] public readonly partial record struct MassPerSquare -//{ -// [CollectionsOperatorsGenerator] public static Pressure operator *(Boost left, MassPerSquare right) => right * left; -// [CollectionsOperatorsGenerator] public static Pressure operator *(MassPerSquare left, Boost right) => left.MultiplyProtected(right, Coeff1); -// static readonly double Coeff1 = Coefficients.MultiplyCoefficient(MassPerSquare.KiloGramPerMeterSquared, Boost.MeterPerSecondSquared, Pressure.Pascal); -//} - -////[CollectionsOperatorsGenerator] public readonly partial record struct PogonForce : Pogon -////{ - - -////} - -////[CollectionsOperatorsGenerator] public readonly partial record struct PogonMass : Pogon -////{ -//// [CollectionsOperatorsGenerator] public static Boost operator /(PogonForce left, PogonMass right) => left.DivideProtected(right, Coeff1); - -//// static readonly double Coeff1 = Coefficients.DivideCoefficient(a => a.PerMilliMeter.Newtons = 1, b => b.PerMilliMeter.KiloGrams = 1, Boost.MeterPerSecondSquared); -////} - -////[CollectionsOperatorsGenerator] public readonly partial record struct UdelForce : Udel -////{ - - -////} - -////[CollectionsOperatorsGenerator] public readonly partial record struct Density : Udel -////{ - - -////} \ No newline at end of file +//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Angle.cs b/QWERTYkez.Mensura/Units/Angle.cs index f03146a..148fd50 100644 --- a/QWERTYkez.Mensura/Units/Angle.cs +++ b/QWERTYkez.Mensura/Units/Angle.cs @@ -3,20 +3,12 @@ /// /// Base value is Seconds /// -[UnitOperatorsGenerator, DebuggerDisplay("Radians = {Radians.ToString(\"0.###\")}, Degrees = {Degrees.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("Radians = {Radians.ToString(\"0.###\")}, Degrees = {Degrees.ToString(\"0.###\")}")] public readonly partial record struct Angle { - [NotMapped, JsonIgnore] public double _Seconds { get => Seconds; init => Seconds = value; } + public static Angle Second { get; } = new() { _Seconds = 1 }; + [NotMapped, JsonIgnore] public double _Seconds { get => _Value; init => _Value = value; } - public static Angle Second { get; } = new() { Seconds = 1 }; - [NotMapped, JsonIgnore] public double Seconds - { - get => _Value; - init - { - _Value = value; - } - } public static Angle Minute { get; } = new() { Minutes = 1 }; [NotMapped, JsonIgnore] public double Minutes diff --git a/QWERTYkez.Mensura/Units/Area.cs b/QWERTYkez.Mensura/Units/Area.cs index 035ae8d..8b07815 100644 --- a/QWERTYkez.Mensura/Units/Area.cs +++ b/QWERTYkez.Mensura/Units/Area.cs @@ -3,20 +3,13 @@ /// /// Base value is MilliMetersSquared /// -[UnitOperatorsGenerator, DebuggerDisplay("mm2 = {_MilliMetersSquared.ToString(\"0.###\")}, m2 = {MetersSquared.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("mm2 = {_MilliMetersSquared.ToString(\"0.###\")}, m2 = {MetersSquared.ToString(\"0.###\")}")] public readonly partial record struct Area { - [NotMapped, JsonIgnore] public double _MilliMetersSquared { get => MilliMetersSquared; init => MilliMetersSquared = value; } + public static Area MilliMeterSquared { get; } = new() { _MilliMetersSquared = 1 }; + [NotMapped, JsonIgnore] public double _MilliMetersSquared { get => _Value; init => _Value = value; } + - public static Area MilliMeterSquared { get; } = new() { MilliMetersSquared = 1 }; - [NotMapped, JsonIgnore] public double MilliMetersSquared - { - get => _Value; - init - { - _Value = value; - } - } public static Area CentiMeterSquared { get; } = new() { CentiMetersSquared = 1 }; [NotMapped, JsonIgnore] public double CentiMetersSquared { diff --git a/QWERTYkez.Mensura/Units/Boost.cs b/QWERTYkez.Mensura/Units/Boost.cs index cf6662d..b2dc2c6 100644 --- a/QWERTYkez.Mensura/Units/Boost.cs +++ b/QWERTYkez.Mensura/Units/Boost.cs @@ -3,20 +3,12 @@ /// /// Base value is MetersPerSecondSquared /// -[UnitOperatorsGenerator, DebuggerDisplay("m/s2 = {_MetersPerSecondSquared.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("m/s2 = {_MetersPerSecondSquared.ToString(\"0.###\")}")] public readonly partial record struct Boost { - [NotMapped, JsonIgnore] public double _MetersPerSecondSquared { get => MetersPerSecondSquared; init => MetersPerSecondSquared = value; } + public static Boost MeterPerSecondSquared { get; } = new() { _MetersPerSecondSquared = 1 }; + [NotMapped, JsonIgnore] public double _MetersPerSecondSquared { get => _Value; init => _Value = value; } - public static Boost MeterPerSecondSquared { get; } = new() { MetersPerSecondSquared = 1 }; - [NotMapped, JsonIgnore] public double MetersPerSecondSquared - { - get => _Value; - init - { - _Value = value; - } - } public static Boost KiloMeterPerSecondSquared { get; } = new() { KiloMetersPerSecondSquared = 1 }; [NotMapped, JsonIgnore] public double KiloMetersPerSecondSquared @@ -28,7 +20,7 @@ public readonly partial record struct Boost } } - public static Boost G { get; } = new() { MetersPerSecondSquared = Constants.g }; + public static Boost G { get; } = new() { _MetersPerSecondSquared = Constants.g }; public Boost AddMetersPerSecondSquared(double value) => new(_Value + value); public Boost AddKiloMetersPerSecondSquared(double value) => new(_Value + BoostConv.KiloMetersPerSecondSquared.To(value)); diff --git a/QWERTYkez.Mensura/Units/Complex/ForceLinear.cs b/QWERTYkez.Mensura/Units/Complex/ForceLinear.cs new file mode 100644 index 0000000..9ec525e --- /dev/null +++ b/QWERTYkez.Mensura/Units/Complex/ForceLinear.cs @@ -0,0 +1,78 @@ +namespace QWERTYkez.Mensura.Units.Complex; + +[ComplexUnitGenerator(nameof(Force), nameof(Length), nameof(ForceLinear))] public readonly partial record struct ForceLinear +{ + public static ForceLinear _NewtonPerMilliMeter { get; } = new() { _PerMilliMeter = new() { _Newtons = 1 } }; + public static ForceLinear KiloGramForcePerMilliMeter { get; } = new() { _PerMilliMeter = new() { KiloGramForces = 1 } }; + public static ForceLinear KiloNewtonPerMilliMeter { get; } = new() { _PerMilliMeter = new() { KiloNewtons = 1 } }; + public static ForceLinear TonForcePerMilliMeter { get; } = new() { _PerMilliMeter = new() { TonForces = 1 } }; + [NotMapped, JsonIgnore] public Force _PerMilliMeter + { get => (Force)_Value; init => _Value = (double)value; } + + + public static ForceLinear NewtonPerCentiMeter { get; } = new() { PerCentiMeter = new() { _Newtons = 1 } }; + public static ForceLinear KiloGramForcePerCentiMeter { get; } = new() { PerCentiMeter = new() { KiloGramForces = 1 } }; + public static ForceLinear KiloNewtonPerCentiMeter { get; } = new() { PerCentiMeter = new() { KiloNewtons = 1 } }; + public static ForceLinear TonForcePerCentiMeter { get; } = new() { PerCentiMeter = new() { TonForces = 1 } }; + [NotMapped, JsonIgnore] public Force PerCentiMeter + { + get => new(_Value * LengthConv.CentiMeters.Multiplicator); + init => _Value = value._Value / LengthConv.CentiMeters.Multiplicator; + } + + + public static ForceLinear NewtonPerDeciMeter { get; } = new() { PerDeciMeter = new() { _Newtons = 1 } }; + public static ForceLinear KiloGramForcePerDeciMeter { get; } = new() { PerDeciMeter = new() { KiloGramForces = 1 } }; + public static ForceLinear KiloNewtonPerDeciMeter { get; } = new() { PerDeciMeter = new() { KiloNewtons = 1 } }; + public static ForceLinear TonForcePerDeciMeter { get; } = new() { PerDeciMeter = new() { TonForces = 1 } }; + + [NotMapped, JsonIgnore] public Force PerDeciMeter + { + get => new(_Value * LengthConv.DeciMeters.Multiplicator); + init => _Value = value._Value / LengthConv.DeciMeters.Multiplicator; + } + + + public static ForceLinear NewtonPerMeter { get; } = new() { PerMeter = new() { _Newtons = 1 } }; + public static ForceLinear KiloGramForcePerMeter { get; } = new() { PerMeter = new() { KiloGramForces = 1 } }; + public static ForceLinear KiloNewtonPerMeter { get; } = new() { PerMeter = new() { KiloNewtons = 1 } }; + public static ForceLinear TonForcePerMeter { get; } = new() { PerMeter = new() { TonForces = 1 } }; + + [NotMapped, JsonIgnore] public Force PerMeter + { + get => new(_Value * LengthConv.Meters.Multiplicator); + init => _Value = value._Value / LengthConv.Meters.Multiplicator; + } + + + public static ForceLinear NewtonPerKiloMeter { get; } = new() { PerKiloMeter = new() { _Newtons = 1 } }; + public static ForceLinear KiloGramForcePerKiloMeter { get; } = new() { PerKiloMeter = new() { KiloGramForces = 1 } }; + public static ForceLinear KiloNewtonPerKiloMeter { get; } = new() { PerKiloMeter = new() { KiloNewtons = 1 } }; + public static ForceLinear TonForcePerKiloMeter { get; } = new() { PerKiloMeter = new() { TonForces = 1 } }; + + [NotMapped, JsonIgnore] public Force PerKiloMeter + { + get => new(_Value * LengthConv.KiloMeters.Multiplicator); + init => _Value = value._Value / LengthConv.KiloMeters.Multiplicator; + } + +} + + + + + +//namespace MetricSystem; + +//[DebuggerDisplay("N/m = {PerMeter._Newtons.ToString(\"0.###\")}, kgf/m = {PerMeter.KiloGramXXXXXXXXs.ToString(\"0.###\")}")] +//public readonly partial record struct PogonXXXXXXXX +//{ + + +//} + +//public partial class Length : Metric +//{ +// [CollectionsOperatorsGenerator] public static PogonXXXXXXXX operator /(XXXXXXXX left, Length right) => left.DivideProtected(right, PogonXXXXXXXXCoeff); +// static readonly double PogonXXXXXXXXCoeff = Coefficients.DivideCoefficient(a => a.Value = 1, b => b._MilliMeters = 1, r => r._PerMilliMeter.Value = 1); +//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Complex/ForceVolumetric.cs b/QWERTYkez.Mensura/Units/Complex/ForceVolumetric.cs new file mode 100644 index 0000000..eaa2d57 --- /dev/null +++ b/QWERTYkez.Mensura/Units/Complex/ForceVolumetric.cs @@ -0,0 +1,56 @@ +namespace QWERTYkez.Mensura.Units.Complex; + +[ComplexUnitGenerator(nameof(Force), nameof(Volume), nameof(ForceVolumetric))] public readonly partial record struct ForceVolumetric +{ + public static ForceVolumetric _NewtonPerMilliMeterCubic { get; } = new() { _PerMilliMeterCubic = new() { _Newtons = 1 } }; + public static ForceVolumetric KiloGramForcePerMilliMeterCubic { get; } = new() { _PerMilliMeterCubic = new() { KiloGramForces = 1 } }; + public static ForceVolumetric KiloNewtonPerMilliMeterCubic { get; } = new() { _PerMilliMeterCubic = new() { KiloNewtons = 1 } }; + public static ForceVolumetric TonForcePerMilliMeterCubic { get; } = new() { _PerMilliMeterCubic = new() { TonForces = 1 } }; + [NotMapped, JsonIgnore] public Force _PerMilliMeterCubic + { get => (Force)_Value; init => _Value = (double)value; } + + + public static ForceVolumetric NewtonPerCentiMeterCubic { get; } = new() { PerCentiMeterCubic = new() { _Newtons = 1 } }; + public static ForceVolumetric KiloGramForcePerCentiMeterCubic { get; } = new() { PerCentiMeterCubic = new() { KiloGramForces = 1 } }; + public static ForceVolumetric KiloNewtonPerCentiMeterCubic { get; } = new() { PerCentiMeterCubic = new() { KiloNewtons = 1 } }; + public static ForceVolumetric TonForcePerCentiMeterCubic { get; } = new() { PerCentiMeterCubic = new() { TonForces = 1 } }; + [NotMapped, JsonIgnore] public Force PerCentiMeterCubic + { + get => new(_Value * VolumeConv.CentiMetersCubic.Multiplicator); + init => _Value = value._Value / VolumeConv.CentiMetersCubic.Multiplicator; + } + + + public static ForceVolumetric NewtonPerMeterCubic { get; } = new() { PerMeterCubic = new() { _Newtons = 1 } }; + public static ForceVolumetric KiloGramForcePerMeterCubic { get; } = new() { PerMeterCubic = new() { KiloGramForces = 1 } }; + public static ForceVolumetric KiloNewtonPerMeterCubic { get; } = new() { PerMeterCubic = new() { KiloNewtons = 1 } }; + public static ForceVolumetric TonForcePerMeterCubic { get; } = new() { PerMeterCubic = new() { TonForces = 1 } }; + + [NotMapped, JsonIgnore] public Force PerMeterCubic + { + get => new(_Value * VolumeConv.MetersCubic.Multiplicator); + init => _Value = value._Value / VolumeConv.MetersCubic.Multiplicator; + } + +} + + + + + +//namespace MetricSystem; + +//[Owned, JsonConverter(typeof(MetricFormatter)), DebuggerDisplay("N/(m*mm2) = {PerMeter_PerMilliMeterSquared._Newtons.ToString(\"0.###\")}, kgf/(m*mm2) = {PerMeter_PerMilliMeterSquared.KiloGramForces.ToString(\"0.###\")}")] +//public partial class ForceVolumetric : Udel +//{ +// [CollectionsOperatorsGenerator] public static ForceVolumetric operator *(Area left, ForceVolumetric right) => right * left; + +// [CollectionsOperatorsGenerator] public static ForceVolumetric operator *(ForceVolumetric left, Area right) => left.MultiplyProtected(right, ForceVolumetricCoeff); +// static readonly double ForceVolumetricCoeff = Coefficients.MultiplyCoefficient(a => a._PerMilliMeterCubic.Value = 1, b => b._MilliMetersSquared = 1, r => r._PerMilliMeter.Value = 1); +//} + +//public partial class Volume : Metric +//{ +// [CollectionsOperatorsGenerator] public static ForceVolumetric operator /(Force left, Volume right) => left.DivideProtected(right, ForceVolumetricCoeff); +// static readonly double ForceVolumetricCoeff = Coefficients.DivideCoefficient(a => a.Value = 1, b => b._MilliMetersCubic = 1, r => r._PerMilliMeterCubic.Value = 1); +//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Complex/MassLinear.cs b/QWERTYkez.Mensura/Units/Complex/MassLinear.cs new file mode 100644 index 0000000..e3682ad --- /dev/null +++ b/QWERTYkez.Mensura/Units/Complex/MassLinear.cs @@ -0,0 +1,82 @@ +namespace QWERTYkez.Mensura.Units.Complex; + +[ComplexUnitGenerator(nameof(Mass), nameof(Length), nameof(MassLinear))] public readonly partial record struct MassLinear +{ + public static MassLinear _GramPerMilliMeter { get; } = new() { _PerMilliMeter = new() { _Grams = 1 } }; + public static MassLinear KiloGramPerMilliMeter { get; } = new() { _PerMilliMeter = new() { KiloGrams = 1 } }; + public static MassLinear CentnerPerMilliMeter { get; } = new() { _PerMilliMeter = new() { Centners = 1 } }; + public static MassLinear TonPerMilliMeter { get; } = new() { _PerMilliMeter = new() { Tons = 1 } }; + [NotMapped, JsonIgnore] public Mass _PerMilliMeter + { get => (Mass)_Value; init => _Value = (double)value; } + + + public static MassLinear GramPerCentiMeter { get; } = new() { PerCentiMeter = new() { _Grams = 1 } }; + public static MassLinear KiloGramPerCentiMeter { get; } = new() { PerCentiMeter = new() { KiloGrams = 1 } }; + public static MassLinear CentnerPerCentiMeter { get; } = new() { PerCentiMeter = new() { Centners = 1 } }; + public static MassLinear TonPerCentiMeter { get; } = new() { PerCentiMeter = new() { Tons = 1 } }; + [NotMapped, JsonIgnore] public Mass PerCentiMeter + { + get => new(_Value * LengthConv.CentiMeters.Multiplicator); + init => _Value = value._Value / LengthConv.CentiMeters.Multiplicator; + } + + + public static MassLinear GramPerDeciMeter { get; } = new() { PerDeciMeter = new() { _Grams = 1 } }; + public static MassLinear KiloGramPerDeciMeter { get; } = new() { PerDeciMeter = new() { KiloGrams = 1 } }; + public static MassLinear CentnerPerDeciMeter { get; } = new() { PerDeciMeter = new() { Centners = 1 } }; + public static MassLinear TonPerDeciMeter { get; } = new() { PerDeciMeter = new() { Tons = 1 } }; + + [NotMapped, JsonIgnore] public Mass PerDeciMeter + { + get => new(_Value * LengthConv.DeciMeters.Multiplicator); + init => _Value = value._Value / LengthConv.DeciMeters.Multiplicator; + } + + + public static MassLinear GramPerMeter { get; } = new() { PerMeter = new() { _Grams = 1 } }; + public static MassLinear KiloGramPerMeter { get; } = new() { PerMeter = new() { KiloGrams = 1 } }; + public static MassLinear CentnerPerMeter { get; } = new() { PerMeter = new() { Centners = 1 } }; + public static MassLinear TonPerMeter { get; } = new() { PerMeter = new() { Tons = 1 } }; + + [NotMapped, JsonIgnore] public Mass PerMeter + { + get => new(_Value * LengthConv.Meters.Multiplicator); + init => _Value = value._Value / LengthConv.Meters.Multiplicator; + } + + + public static MassLinear GramPerKiloMeter { get; } = new() { PerKiloMeter = new() { _Grams = 1 } }; + public static MassLinear KiloGramPerKiloMeter { get; } = new() { PerKiloMeter = new() { KiloGrams = 1 } }; + public static MassLinear CentnerPerKiloMeter { get; } = new() { PerKiloMeter = new() { Centners = 1 } }; + public static MassLinear TonPerKiloMeter { get; } = new() { PerKiloMeter = new() { Tons = 1 } }; + + [NotMapped, JsonIgnore] public Mass PerKiloMeter + { + get => new(_Value * LengthConv.KiloMeters.Multiplicator); + init => _Value = value._Value / LengthConv.KiloMeters.Multiplicator; + } + +} + + + + + + + + + + + +//[Owned, JsonConverter(typeof(MetricFormatter)), DebuggerDisplay("gr/m = {PerMeter._Grams.ToString(\"0.###\")}, kg/m = {PerMeter.KiloGrams.ToString(\"0.###\")}")] +//public partial class MassLinear : Pogon +//{ +// [CollectionsOperatorsGenerator] public static Density operator /(MassLinear left, Area right) => left.DivideProtected(right, UdelMassCoeff); +// static readonly double UdelMassCoeff = Coefficients.DivideCoefficient(a => a._PerMilliMeter.Value = 1, b => b._MilliMetersSquared = 1, r => r._PerMilliMeterCubic.Value = 1); +//} + +//public partial class Length : Metric +//{ +// [CollectionsOperatorsGenerator] public static MassLinear operator /(Mass left, Length right) => left.DivideProtected(right, MassLinearCoeff); +// static readonly double MassLinearCoeff = Coefficients.DivideCoefficient(a => a.Value = 1, b => b._MilliMeters = 1, r => r._PerMilliMeter.Value = 1); +//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Complex/MassVolumetric (Density).cs b/QWERTYkez.Mensura/Units/Complex/MassVolumetric (Density).cs new file mode 100644 index 0000000..c096ea1 --- /dev/null +++ b/QWERTYkez.Mensura/Units/Complex/MassVolumetric (Density).cs @@ -0,0 +1,59 @@ +namespace QWERTYkez.Mensura.Units.Complex; + +[ComplexUnitGenerator(nameof(Mass), nameof(Volume), nameof(Density))] public readonly partial record struct Density +{ + public static Density _GramPerMilliMeterCubic { get; } = new() { _PerMilliMeterCubic = new() { _Grams = 1 } }; + public static Density KiloGramPerMilliMeterCubic { get; } = new() { _PerMilliMeterCubic = new() { KiloGrams = 1 } }; + public static Density CentnerPerMilliMeterCubic { get; } = new() { _PerMilliMeterCubic = new() { Centners = 1 } }; + public static Density TonPerMilliMeterCubic { get; } = new() { _PerMilliMeterCubic = new() { Tons = 1 } }; + [NotMapped, JsonIgnore] public Mass _PerMilliMeterCubic + { get => (Mass)_Value; init => _Value = (double)value; } + + + public static Density GramPerCentiMeterCubic { get; } = new() { PerCentiMeterCubic = new() { _Grams = 1 } }; + public static Density KiloGramPerCentiMeterCubic { get; } = new() { PerCentiMeterCubic = new() { KiloGrams = 1 } }; + public static Density CentnerPerCentiMeterCubic { get; } = new() { PerCentiMeterCubic = new() { Centners = 1 } }; + public static Density TonPerCentiMeterCubic { get; } = new() { PerCentiMeterCubic = new() { Tons = 1 } }; + [NotMapped, JsonIgnore] public Mass PerCentiMeterCubic + { + get => new(_Value * VolumeConv.CentiMetersCubic.Multiplicator); + init => _Value = value._Value / VolumeConv.CentiMetersCubic.Multiplicator; + } + + + public static Density GramPerMeterCubic { get; } = new() { PerMeterCubic = new() { _Grams = 1 } }; + public static Density KiloGramPerMeterCubic { get; } = new() { PerMeterCubic = new() { KiloGrams = 1 } }; + public static Density CentnerPerMeterCubic { get; } = new() { PerMeterCubic = new() { Centners = 1 } }; + public static Density TonPerMeterCubic { get; } = new() { PerMeterCubic = new() { Tons = 1 } }; + + [NotMapped, JsonIgnore] public Mass PerMeterCubic + { + get => new(_Value * VolumeConv.MetersCubic.Multiplicator); + init => _Value = value._Value / VolumeConv.MetersCubic.Multiplicator; + } + +} + + + + + + + + +//namespace MetricSystem; + +//[Owned, JsonConverter(typeof(MetricFormatter)), DebuggerDisplay("gr/(m*mm2) = {PerMeterCubic_PerMilliMetersCubicquared._Grams.ToString(\"0.###\")}, kg/(m*mm2) = {PerMeterCubic_PerMilliMetersCubicquared.KiloGrams.ToString(\"0.###\")}")] +//public partial class Density : Udel +//{ +// [CollectionsOperatorsGenerator] public static PogonMass operator *(Area left, Density right) => right * left; + +// [CollectionsOperatorsGenerator] public static PogonMass operator *(Density left, Area right) => left.MultiplyProtected(right, PogonMassCoeff); +// static readonly double PogonMassCoeff = Coefficients.MultiplyCoefficient(a => a._PerMilliMeterCubicCubic.Value = 1, b => b._MilliMetersCubicSquared = 1, r => r._PerMilliMeterCubic.Value = 1); +//} + +//public partial class Volume : Metric +//{ +// [CollectionsOperatorsGenerator] public static Density operator /(Mass left, Volume right) => left.DivideProtected(right, DensityCoeff); +// static readonly double DensityCoeff = Coefficients.DivideCoefficient(a => a.Value = 1, b => b._MilliMetersCubicCubic = 1, r => r._PerMilliMeterCubicCubic.Value = 1); +//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Force.cs b/QWERTYkez.Mensura/Units/Force.cs index 9a33606..499135a 100644 --- a/QWERTYkez.Mensura/Units/Force.cs +++ b/QWERTYkez.Mensura/Units/Force.cs @@ -3,20 +3,12 @@ /// /// Base value is Newtons /// -[UnitOperatorsGenerator, DebuggerDisplay("N = {_Newtons.ToString(\"0.###\")}, kgf = {KiloGramForces.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("N = {_Newtons.ToString(\"0.###\")}, kgf = {KiloGramForces.ToString(\"0.###\")}")] public readonly partial record struct Force { - [NotMapped, JsonIgnore] public double _Newtons { get => Newtons; init => Newtons = value; } + public static Force Newton { get; } = new() { _Newtons = 1 }; + [NotMapped, JsonIgnore] public double _Newtons { get => _Value; init => _Value = value; } - public static Force Newton { get; } = new() { Newtons = 1 }; - [NotMapped, JsonIgnore] public double Newtons - { - get => _Value; - init - { - _Value = value; - } - } public static Force KiloGramForce { get; } = new() { KiloGramForces = 1 }; [NotMapped, JsonIgnore] public double KiloGramForces diff --git a/QWERTYkez.Mensura/Units/Frequency.cs b/QWERTYkez.Mensura/Units/Frequency.cs index 2e43fc1..15c72ce 100644 --- a/QWERTYkez.Mensura/Units/Frequency.cs +++ b/QWERTYkez.Mensura/Units/Frequency.cs @@ -3,20 +3,12 @@ /// /// Base value is Hertz /// -[UnitOperatorsGenerator, DebuggerDisplay("Hz = {_Hertz.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("Hz = {_Hertz.ToString(\"0.###\")}")] public readonly partial record struct Frequency { - [NotMapped, JsonIgnore] public double _Hertz { get => Hertz; init => Hertz = value; } + public static Frequency OneHertz { get; } = new() { _Hertz = 1 }; + [NotMapped, JsonIgnore] public double _Hertz { get => _Value; init => _Value = value; } - public static Frequency OneHertz { get; } = new() { Hertz = 1 }; - [NotMapped, JsonIgnore] public double Hertz - { - get => _Value; - init - { - _Value = value; - } - } public static Frequency OneKiloHertz { get; } = new() { KiloHertz = 1 }; [NotMapped, JsonIgnore] public double KiloHertz diff --git a/QWERTYkez.Mensura/Units/Length.cs b/QWERTYkez.Mensura/Units/Length.cs index bf54d18..5c7fc06 100644 --- a/QWERTYkez.Mensura/Units/Length.cs +++ b/QWERTYkez.Mensura/Units/Length.cs @@ -3,7 +3,7 @@ /// /// Base value is MilliMeters /// -[UnitOperatorsGenerator, DebuggerDisplay("mm = {_MilliMeters.ToString(\"0.###\")}, m = {Meters.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("mm = {_MilliMeters.ToString(\"0.###\")}, m = {Meters.ToString(\"0.###\")}")] public readonly partial record struct Length { public static Length MilliMeter { get; } = new(1); @@ -15,19 +15,8 @@ public readonly partial record struct Length public double CentiMeters { get => LengthConv.CentiMeters.From(_Value); - init - { - Length aaa = new(); - Length bbb = new(); - - if (aaa != bbb || aaa == bbb) - { - - } - - _Value = LengthConv.CentiMeters.To(value); - } - } + init => _Value = LengthConv.CentiMeters.To(value); + } public static Length DeciMeter { get; } = new(LengthConv.DeciMeters.To(1)); [NotMapped, JsonIgnore] diff --git a/QWERTYkez.Mensura/Units/Mass.cs b/QWERTYkez.Mensura/Units/Mass.cs index 92f81a0..9eae302 100644 --- a/QWERTYkez.Mensura/Units/Mass.cs +++ b/QWERTYkez.Mensura/Units/Mass.cs @@ -3,20 +3,12 @@ /// /// Base value is Grams /// -[UnitOperatorsGenerator, DebuggerDisplay("gr = {_Grams.ToString(\"0.###\")}, kg = {KiloGrams.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("gr = {_Grams.ToString(\"0.###\")}, kg = {KiloGrams.ToString(\"0.###\")}")] public readonly partial record struct Mass { - [NotMapped, JsonIgnore] public double _Grams { get => Grams; init => Grams = value; } + public static Mass Gram { get; } = new() { _Grams = 1 }; + [NotMapped, JsonIgnore] public double _Grams { get => _Value; init => _Value = value; } - public static Mass Gram { get; } = new() { Grams = 1 }; - [NotMapped, JsonIgnore] public double Grams - { - get => _Value; - init - { - _Value = value; - } - } public static Mass KiloGram { get; } = new() { KiloGrams = 1 }; [NotMapped, JsonIgnore] public double KiloGrams diff --git a/QWERTYkez.Mensura/Units/MassPerSquare.cs b/QWERTYkez.Mensura/Units/MassPerSquare.cs index a06ff46..97294ae 100644 --- a/QWERTYkez.Mensura/Units/MassPerSquare.cs +++ b/QWERTYkez.Mensura/Units/MassPerSquare.cs @@ -3,20 +3,12 @@ /// /// Base value is KiloGramsPerMeterSquared /// -[UnitOperatorsGenerator, DebuggerDisplay("kg/m2 = {_KiloGramsPerMeterSquared.ToString(\"0.###\")}, kg/mm2 = {KiloGramsPerMilliMeterSquared.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("kg/m2 = {_KiloGramsPerMeterSquared.ToString(\"0.###\")}, kg/mm2 = {KiloGramsPerMilliMeterSquared.ToString(\"0.###\")}")] public readonly partial record struct MassPerSquare { - [NotMapped, JsonIgnore] public double _KiloGramsPerMeterSquared { get => KiloGramsPerMeterSquared; init => KiloGramsPerMeterSquared = value; } + public static MassPerSquare KiloGramPerMeterSquared { get; } = new() { _KiloGramsPerMeterSquared = 1 }; + [NotMapped, JsonIgnore] public double _KiloGramsPerMeterSquared { get => _Value; init => _Value = value; } - public static MassPerSquare KiloGramPerMeterSquared { get; } = new() { KiloGramsPerMeterSquared = 1 }; - [NotMapped, JsonIgnore] public double KiloGramsPerMeterSquared - { - get => _Value; - init - { - _Value = value; - } - } public static MassPerSquare KiloGramPerMilliMeterSquared { get; } = new() { KiloGramsPerMilliMeterSquared = 1 }; [NotMapped, JsonIgnore] public double KiloGramsPerMilliMeterSquared diff --git a/QWERTYkez.Mensura/Units/Pogon/PogonForce.cs b/QWERTYkez.Mensura/Units/Pogon/PogonForce.cs deleted file mode 100644 index 7302a22..0000000 --- a/QWERTYkez.Mensura/Units/Pogon/PogonForce.cs +++ /dev/null @@ -1,14 +0,0 @@ -//namespace MetricSystem; - -//[DebuggerDisplay("N/m = {PerMeter._Newtons.ToString(\"0.###\")}, kgf/m = {PerMeter.KiloGramXXXXXXXXs.ToString(\"0.###\")}")] -//public readonly partial record struct PogonXXXXXXXX -//{ - - -//} - -//public partial class Length : Metric -//{ -// [CollectionsOperatorsGenerator] public static PogonXXXXXXXX operator /(XXXXXXXX left, Length right) => left.DivideProtected(right, PogonXXXXXXXXCoeff); -// static readonly double PogonXXXXXXXXCoeff = Coefficients.DivideCoefficient(a => a.Value = 1, b => b._MilliMeters = 1, r => r._PerMilliMeter.Value = 1); -//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Pogon/PogonMass.cs b/QWERTYkez.Mensura/Units/Pogon/PogonMass.cs deleted file mode 100644 index 3775e6d..0000000 --- a/QWERTYkez.Mensura/Units/Pogon/PogonMass.cs +++ /dev/null @@ -1,14 +0,0 @@ -//namespace MetricSystem; - -//[Owned, JsonConverter(typeof(MetricFormatter)), DebuggerDisplay("gr/m = {PerMeter._Grams.ToString(\"0.###\")}, kg/m = {PerMeter.KiloGrams.ToString(\"0.###\")}")] -//public partial class PogonMass : Pogon -//{ -// [CollectionsOperatorsGenerator] public static Density operator /(PogonMass left, Area right) => left.DivideProtected(right, UdelMassCoeff); -// static readonly double UdelMassCoeff = Coefficients.DivideCoefficient(a => a._PerMilliMeter.Value = 1, b => b._MilliMetersSquared = 1, r => r._PerMilliMeterCubic.Value = 1); -//} - -//public partial class Length : Metric -//{ -// [CollectionsOperatorsGenerator] public static PogonMass operator /(Mass left, Length right) => left.DivideProtected(right, PogonMassCoeff); -// static readonly double PogonMassCoeff = Coefficients.DivideCoefficient(a => a.Value = 1, b => b._MilliMeters = 1, r => r._PerMilliMeter.Value = 1); -//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Pogon/PogonXXXXXXXX.Gen.cs b/QWERTYkez.Mensura/Units/Pogon/PogonXXXXXXXX.Gen.cs index 26bfdfd..af7f530 100644 --- a/QWERTYkez.Mensura/Units/Pogon/PogonXXXXXXXX.Gen.cs +++ b/QWERTYkez.Mensura/Units/Pogon/PogonXXXXXXXX.Gen.cs @@ -1,775 +1,481 @@ -#if DEBUG -global using PogonMassExtensions = QWERTYkez.Mensura.Units.Pogon.PogonMassExtensions; -global using PogonMassConverter = QWERTYkez.Mensura.Units.Pogon.PogonMassConverter; -global using PogonMass = QWERTYkez.Mensura.Units.Pogon.PogonMass; +//#if DEBUG + +//// Generated + +//global using PogonAAAAAAAAAAAAAAAAExtensions = QWERTYkez.Mensura.Units.Pogon.PogonAAAAAAAAAAAAAAAAExtensions; +//global using PogonAAAAAAAAAAAAAAAAConverter = QWERTYkez.Mensura.Units.Pogon.PogonAAAAAAAAAAAAAAAAConverter; +//global using ZZZZZZZZZZZZZZZZ = QWERTYkez.Mensura.Units.Pogon.ZZZZZZZZZZZZZZZZ; + +//using System.Globalization; +//using System.Runtime.Serialization; + +//namespace QWERTYkez.Mensura.Units +//{ +// public readonly partial record struct BBBBBBBBBBBBBBBB +// { +// public static ZZZZZZZZZZZZZZZZ operator /(AAAAAAAAAAAAAAAA left, BBBBBBBBBBBBBBBB right) => new(left._Value / right._Value); +// public static ZZZZZZZZZZZZZZZZ operator /(AAAAAAAAAAAAAAAA? left, BBBBBBBBBBBBBBBB right) => new(left.Protected() / right._Value); +// public static ZZZZZZZZZZZZZZZZ operator /(AAAAAAAAAAAAAAAA left, BBBBBBBBBBBBBBBB? right) => new(left._Value / right.Protected()); +// public static ZZZZZZZZZZZZZZZZ operator /(AAAAAAAAAAAAAAAA? left, BBBBBBBBBBBBBBBB? right) => new(left.Protected() / right.Protected()); + + +// // === Array === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA[] operator +// *(ZZZZZZZZZZZZZZZZ[] units, BBBBBBBBBBBBBBBB multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA?[] operator +// *(ZZZZZZZZZZZZZZZZ?[] units, BBBBBBBBBBBBBBBB multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA[] operator +// *(BBBBBBBBBBBBBBBB multiplicator, ZZZZZZZZZZZZZZZZ[] units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA?[] operator +// *(BBBBBBBBBBBBBBBB multiplicator, ZZZZZZZZZZZZZZZZ?[] units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA[] operator *(ZZZZZZZZZZZZZZZZ[] units, BBBBBBBBBBBBBBBB? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new AAAAAAAAAAAAAAAA[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA?[] operator *(ZZZZZZZZZZZZZZZZ?[] units, BBBBBBBBBBBBBBBB? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new AAAAAAAAAAAAAAAA?[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA[] operator *(BBBBBBBBBBBBBBBB? multiplicator, ZZZZZZZZZZZZZZZZ[] units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new AAAAAAAAAAAAAAAA[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA?[] operator *(BBBBBBBBBBBBBBBB? multiplicator, ZZZZZZZZZZZZZZZZ?[] units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new AAAAAAAAAAAAAAAA?[units.Length]); + +// // === List === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// *(List units, BBBBBBBBBBBBBBBB multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// *(List units, BBBBBBBBBBBBBBBB multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// *(BBBBBBBBBBBBBBBB multiplicator, List units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// *(BBBBBBBBBBBBBBBB multiplicator, List units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(List units, BBBBBBBBBBBBBBBB? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(List units, BBBBBBBBBBBBBBBB? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(BBBBBBBBBBBBBBBB? multiplicator, List units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(BBBBBBBBBBBBBBBB? multiplicator, List units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); + +// // === IEnumerable === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// *(IEnumerable units, BBBBBBBBBBBBBBBB multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// *(IEnumerable units, BBBBBBBBBBBBBBBB multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// *(BBBBBBBBBBBBBBBB multiplicator, IEnumerable units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// *(BBBBBBBBBBBBBBBB multiplicator, IEnumerable units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(IEnumerable units, BBBBBBBBBBBBBBBB? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new AAAAAAAAAAAAAAAA(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(IEnumerable units, BBBBBBBBBBBBBBBB? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? (AAAAAAAAAAAAAAAA?)null : new AAAAAAAAAAAAAAAA(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(BBBBBBBBBBBBBBBB? multiplicator, IEnumerable units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new AAAAAAAAAAAAAAAA(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(BBBBBBBBBBBBBBBB? multiplicator, IEnumerable units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? (AAAAAAAAAAAAAAAA?)null : new AAAAAAAAAAAAAAAA(0d))); -using System.Globalization; -using System.Runtime.Serialization; -namespace QWERTYkez.Mensura.Units -{ - public readonly partial record struct Length - { - // === Array === - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass[] operator - *(PogonMass[] units, Length multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass?[] operator - *(PogonMass?[] units, Length multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass[] operator - *(Length multiplicator, PogonMass[] units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass?[] operator - *(Length multiplicator, PogonMass?[] units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass[] operator *(PogonMass[] units, Length? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new Mass[units.Length]); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass?[] operator *(PogonMass?[] units, Length? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new Mass?[units.Length]); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass[] operator *(Length? multiplicator, PogonMass[] units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new Mass[units.Length]); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass?[] operator *(Length? multiplicator, PogonMass?[] units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new Mass?[units.Length]); - // === List === - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator - *(List units, Length multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator - *(List units, Length multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator - *(Length multiplicator, List units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator - *(Length multiplicator, List units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(List units, Length? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(List units, Length? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(Length? multiplicator, List units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(Length? multiplicator, List units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); - // === IEnumerable === - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator - *(IEnumerable units, Length multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator - *(IEnumerable units, Length multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator - *(Length multiplicator, IEnumerable units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator - *(Length multiplicator, IEnumerable units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(IEnumerable units, Length? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new Mass(0d))); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(IEnumerable units, Length? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? (Mass?)null : new Mass(0d))); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(Length? multiplicator, IEnumerable units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new Mass(0d))); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(Length? multiplicator, IEnumerable units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? (Mass?)null : new Mass(0d))); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //// ========================================== - //// === MULTIPLY === - //// ========================================== - - //public static Mass[] operator *(PogonMass[] left, Length right) - //{ - // if (left is null) return null!; - // int len = left.Length; - // if (len == 0) return []; - - // var result = new Mass[len]; - // PogonMassExtensions.MultiplyCore(left, right, result); - // return result; - //} - //public static Mass[] operator *(PogonMass[] left, Length? right) - //{ - // if (left is null) return null!; - // int len = left.Length; - // if (len == 0) return []; - - // var result = new Mass[len]; - // if (right is { } val) - // for (int i = 0; i < len; i++) - // result[i] = val * left[i]; - // return result; - //} - //public static Mass[] operator *(Length left, PogonMass[] right) - //{ - // if (right is null) return null!; - // int len = right.Length; - // if (len == 0) return []; - - // var result = new Mass[len]; - // for (int i = 0; i < len; i++) - // result[i] = left * right[i]; - // return result; - //} - //public static Mass[] operator *(Length? left, PogonMass[] right) - //{ - // if (right is null) return null!; - // int len = right.Length; - // if (len == 0) return []; - - // var result = new Mass[len]; - // if (left is { } val) - // for (int i = 0; i < len; i++) - // result[i] = val * right[i]; - // return result; - //} - - //// === ReadOnlySpan === - - //public static Span operator *(Length left, ReadOnlySpan right) - //{ - // int len = right.Length; - // if (len == 0) return []; - - // Span result = new Mass[len]; - // for (int i = 0; i < len; i++) - // result[i] = left * right[i]; - // return result; - //} - //public static Span operator *(Length? left, ReadOnlySpan right) - //{ - // int len = right.Length; - // if (len == 0) return []; - - // Span result = new Mass[len]; - // if (left is { } val) - // for (int i = 0; i < len; i++) - // result[i] = val * right[i]; - // return result; - //} - //public static Span operator *(ReadOnlySpan left, Length right) - //{ - // int len = left.Length; - // if (len == 0) return []; - - // Span result = new Mass[len]; - // for (int i = 0; i < len; i++) - // result[i] = right * left[i]; - // return result; - //} - //public static Span operator *(ReadOnlySpan left, Length? right) - //{ - // int len = left.Length; - // if (len == 0) return []; - - // Span result = new Mass[len]; - // if (right is { } val) - // for (int i = 0; i < len; i++) - // result[i] = val * left[i]; - // return result; - //} - - //// === List === - - //public static List operator *(Length left, List right) - //{ - // if (right is null) return null!; - // int len = right.Count; - // if (len == 0) return []; - - // var result = new List(len); - // for (int i = 0; i < len; i++) - // result[i] = left * right[i]; - // return result; - //} - //public static List operator *(Length? left, List right) - //{ - // if (right is null) return null!; - // int len = right.Count; - // if (len == 0) return []; - - // var result = new List(len); - // if (left is { } val) - // for (int i = 0; i < len; i++) - // result[i] = val * right[i]; - // return result; - //} - //public static List operator *(List left, Length right) - //{ - // if (left is null) return null!; - // int len = left.Count; - // if (len == 0) return []; - - // var result = new List(len); - // for (int i = 0; i < len; i++) - // result[i] = right * left[i]; - // return result; - //} - //public static List operator *(List left, Length? right) - //{ - // if (left is null) return null!; - // int len = left.Count; - // if (len == 0) return []; - - // var result = new List(len); - // if (right is { } val) - // for (int i = 0; i < len; i++) - // result[i] = val * left[i]; - // return result; - //} - - } -} - -namespace QWERTYkez.Mensura.Units.Pogon -{ - [JsonConverter(typeof(PogonMassConverter))] - public readonly partial record struct PogonMass : IMensuraUnit, IEquatable, IMensuraUnit - { - - [JsonInclude, DataMember, JsonPropertyName("v"), Obsolete] // для JSON / EF на случай сбоев, если пробелма с _Value - internal double Value { get => _Value; init => _Value = value; } - internal readonly double _Value; - internal PogonMass(double value) => _Value = value; - - - [NotMapped, JsonIgnore] - internal Mass PerValue - { get => (Mass)_Value; init => _Value = (double)value; } - - - - [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 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 Mass operator *(PogonMass left, Length right) => left.PerValue * right._Value; - public static Mass operator *(PogonMass? left, Length right) => (left ?? default).PerValue * right._Value; - public static Mass operator *(PogonMass left, Length? right) => left.PerValue * (right ?? default)._Value; - public static Mass operator *(PogonMass? left, Length? right) => (left ?? default).PerValue * (right ?? default)._Value; - - public static Mass operator *(Length left, PogonMass right) => right.PerValue * left._Value; - public static Mass operator *(Length? left, PogonMass right) => right.PerValue * (left ?? default)._Value; - public static Mass operator *(Length left, PogonMass? right) => (right ?? default).PerValue * left._Value; - public static Mass operator *(Length? left, PogonMass? right) => (right ?? default).PerValue * (left ?? default)._Value; - - public static Length operator /(Mass left, PogonMass right) => new(left / right.PerValue); - public static Length operator /(Mass? left, PogonMass right) => new((left ?? default) / right.PerValue); - public static Length operator /(Mass left, PogonMass? right) => new(left / (right ?? default).PerValue); - public static Length operator /(Mass? left, PogonMass? right) => new((left ?? default) / (right ?? default).PerValue); - - - - - // === Array === - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass[] operator - *(Length[] units, PogonMass multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass?[] operator - *(Length?[] units, PogonMass multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass[] operator - *(PogonMass multiplicator, Length[] units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass?[] operator - *(PogonMass multiplicator, Length?[] units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass[] operator *(Length[] units, PogonMass? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new Mass[units.Length]); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass?[] operator *(Length?[] units, PogonMass? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new Mass?[units.Length]); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass[] operator *(PogonMass? multiplicator, Length[] units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new Mass[units.Length]); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mass?[] operator *(PogonMass? multiplicator, Length?[] units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new Mass?[units.Length]); - - // === List === - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator - *(List units, PogonMass multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator - *(List units, PogonMass multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator - *(PogonMass multiplicator, List units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator - *(PogonMass multiplicator, List units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(List units, PogonMass? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(List units, PogonMass? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(PogonMass? multiplicator, List units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(PogonMass? multiplicator, List units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); - - // === IEnumerable === - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator - *(IEnumerable units, PogonMass multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator - *(IEnumerable units, PogonMass multiplicator) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator - *(PogonMass multiplicator, IEnumerable units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator - *(PogonMass multiplicator, IEnumerable units) => units.Multiply(multiplicator._Value); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(IEnumerable units, PogonMass? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new Mass(0d))); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(IEnumerable units, PogonMass? multiplicator) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? (Mass?)null : new Mass(0d))); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(PogonMass? multiplicator, IEnumerable units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new Mass(0d))); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(PogonMass? multiplicator, IEnumerable units) => - multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? (Mass?)null : new Mass(0d))); - } - - internal static class PogonMassExtensions - { - internal static Mass Protect(this Mass? unit) => unit ?? default; - internal static double ToDouble(this Length? unit) => unit?._Value ?? 0d; - - - public static Length MetricSum(this IEnumerable units) => new(units?.Sum(m => m._Value) ?? 0d); - public static Length MetricAverage(this IEnumerable units) => new(units?.Average(m => m._Value) ?? double.NaN); - public static Length MetricMax(this IEnumerable units) => new(units?.Max(m => m._Value) ?? double.MinValue); - public static Length MetricMin(this IEnumerable units) => new(units?.Min(m => m._Value) ?? double.MaxValue); - - public static Length MetricSum(this IEnumerable units) => new(units?.Sum(m => m.ToDouble()) ?? 0d); - public static Length MetricAverage(this IEnumerable units) => new(units?.Average(m => m.ToDouble()) ?? double.NaN); - public static Length MetricMax(this IEnumerable units) => new(units?.Max(m => m.ToDouble()) ?? double.MinValue); - public static Length MetricMin(this IEnumerable units) => new(units?.Min(m => m.ToDouble()) ?? double.MaxValue); - - - - - - - - - - - - - - - - - - - - - - // === ReadOnlySpan - public static void Multiply(this ReadOnlySpan units, Length multiplicator, Span destination) - => units.MultiplyCore(multiplicator._Value, destination); - public static void Multiply(this ReadOnlySpan units, Length multiplicator, Span destination) - => units.MultiplyCore(multiplicator._Value, destination); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(this Length multiplicator, - ReadOnlySpan units, Span destination) => units.MultiplyCore(multiplicator._Value, destination); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(this Length multiplicator, - ReadOnlySpan units, Span destination) => units.MultiplyCore(multiplicator._Value, destination); - - // === Array === - public static Mass[] Multiply(this PogonMass[] units, Length multiplicator) - { - if (units is null) return null!; - int len = units.Length; - if (len == 0) return []; - - var result = new Mass[len]; - Multiply(units, multiplicator, result); - return result; - } - public static Mass?[] Multiply(this PogonMass?[] units, Length multiplicator) - { - if (units is null) return null!; - int len = units.Length; - if (len == 0) return []; - - var result = new Mass?[len]; - Multiply(units, multiplicator, result); - return result; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Mass[] Multiply( - this Length multiplicator, PogonMass[] units) => units.Multiply(multiplicator); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Mass?[] Multiply( - this Length multiplicator, PogonMass?[] units) => units.Multiply(multiplicator); - - // === List === - public static List Multiply(this List units, Length multiplicator) - { - if (units is null) return null!; - int len = units.Count; - if (len == 0) return []; - - var resultArray = new Mass[len]; - Multiply(CollectionsMarshal.AsSpan(units), multiplicator, resultArray); - return resultArray.WrapAsList(); - } - public static List Multiply(this List units, Length multiplicator) - { - if (units is null) return null!; - int count = units.Count; - if (count == 0) return []; - - var resultArray = new Mass?[count]; - Multiply(CollectionsMarshal.AsSpan(units), multiplicator, resultArray); - return resultArray.WrapAsList(); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static List Multiply( - this Length multiplicator, List units) => units.Multiply(multiplicator); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static List Multiply( - this Length multiplicator, List units) => units.Multiply(multiplicator); - - // === ICollection === - public static void Multiply(this ICollection units, Length multiplicator, Span destination) - { - if (units is null) return; - int count = units.Count; - if (count == 0) return; - if (destination.Length < count) - throw new ArgumentException("Destination too short"); - - if (units is PogonMass[] array) { array.Multiply(multiplicator, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Multiply(multiplicator, destination); return; } - - int i = 0; - foreach (var item in units) - destination[i++] = (item.ToDouble() * multiplicator._Value).ToUnit(); - } - public static void Multiply(this ICollection units, Length multiplicator, Span destination) - { - if (units is null) return; - int count = units.Count; - if (count == 0) return; - if (destination.Length < count) - throw new ArgumentException("Destination too short"); - - if (units is PogonMass?[] array) { array.Multiply(multiplicator, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Multiply(multiplicator, destination); return; } - - int i = 0; - foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() * multiplicator._Value).ToUnit() : null; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(this Length multiplicator, - ICollection units, Span destination) => units.Multiply(multiplicator, destination); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(this Length multiplicator, - ICollection units, Span destination) => units.Multiply(multiplicator, destination); - - // === IReadOnlyCollection === - public static void Multiply(this IReadOnlyCollection units, Length multiplicator, Span destination) - { - if (units is null) return; - int count = units.Count; - if (count == 0) return; - if (destination.Length < count) - throw new ArgumentException("Destination too short"); - - if (units is PogonMass[] array) { array.Multiply(multiplicator, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Multiply(multiplicator, destination); return; } - - int i = 0; - foreach (var item in units) - destination[i++] = (item.ToDouble() * multiplicator._Value).ToUnit(); - } - public static void Multiply(this IReadOnlyCollection units, Length multiplicator, Span destination) - { - if (units is null) return; - int count = units.Count; - if (count == 0) return; - if (destination.Length < count) - throw new ArgumentException("Destination too short"); - - if (units is PogonMass?[] array) { array.Multiply(multiplicator, destination); return; } - if (units is List list) { CollectionsMarshal.AsSpan(list).Multiply(multiplicator, destination); return; } - - int i = 0; - foreach (var item in units) - destination[i++] = item.HasValue - ? (item.Value.ToDouble() * multiplicator._Value).ToUnit() : null; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(this Length multiplicator, - IReadOnlyCollection units, Span destination) => units.Multiply(multiplicator, destination); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Multiply(this Length multiplicator, - IReadOnlyCollection units, Span destination) => units.Multiply(multiplicator, destination); - - // === IEnumerable + yeild === - static IEnumerable MultiplyIterator(IEnumerable units, Length multiplicator) - { - foreach (var item in units) - yield return (item.ToDouble() * multiplicator._Value).ToUnit(); - } - static IEnumerable MultiplyNullableIterator(IEnumerable units, Length multiplicator) - { - foreach (PogonMass? item in units) - yield return item.HasValue - ? (item.Value.ToDouble() * multiplicator._Value).ToUnit() : null; - } - - // === IEnumerable === - public static IEnumerable Multiply(this IEnumerable units, Length multiplicator) - { - if (units is null) return null!; - if (units is PogonMass[] array) return array.Multiply(multiplicator); - if (units is List list) return list.Multiply(multiplicator); - if (units is ICollection col) - { - var arr = new Mass[col.Count]; - col.Multiply(multiplicator, arr); - return arr; - } - if (units is IReadOnlyCollection roc) - { - var arr = new Mass[roc.Count]; - roc.Multiply(multiplicator, arr); - return arr; - } - return MultiplyIterator(units, multiplicator); - } - public static IEnumerable Multiply(this IEnumerable units, Length multiplicator) - { - if (units is null) return null!; - if (units is PogonMass?[] array) return array.Multiply(multiplicator); - if (units is List list) return list.Multiply(multiplicator); - if (units is ICollection col) - { - var arr = new Mass?[col.Count]; - col.Multiply(multiplicator, arr); - return arr; - } - if (units is IReadOnlyCollection roc) - { - var arr = new Mass?[roc.Count]; - roc.Multiply(multiplicator, arr); - return arr; - } - return MultiplyNullableIterator(units, multiplicator); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IEnumerable Multiply( - this Length multiplicator, IEnumerable units) => Multiply(units, multiplicator); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IEnumerable Multiply( - this Length multiplicator, IEnumerable units) => Multiply(units, multiplicator); - - - - - - - - - - - - - - - - - - - - - - internal static void MultiplyCore(this ReadOnlySpan source, Length value, Span destination) - { - var dVal = value._Value; - source.MultiplyCore(dVal, destination); - } - internal static void MultiplyCore(this ReadOnlySpan source, PogonMass value, Span destination) - { - var dVal = value._Value; - source.Multiply(dVal, destination); - } - - - internal static void DivideCore(this ReadOnlySpan source, PogonMass divisor, Span destination) - { - // 1. Проверка на ноль - if (divisor.IsZero || divisor.IsNaN) - throw new DivideByZeroException("Делитель не может быть равен нулю."); - - var dVal = divisor._Value; - int len = source.Length; - ReadOnlySpan srcDouble = MemoryMarshal.Cast(source); - Span dstDouble = MemoryMarshal.Cast(destination); - - var vectorized_Value = new Vector(dVal); - int vectorSize = Vector.Count; - int i = 0; - - ref double srcRef = ref MemoryMarshal.GetReference(srcDouble); - ref double dstRef = ref MemoryMarshal.GetReference(dstDouble); - - int SIMDEnd = len - (len % vectorSize); - for (; i < SIMDEnd; i += vectorSize) - { - ref double currentSrc = ref Unsafe.Add(ref srcRef, i); - ReadOnlySpan srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize); - var vector = new Vector(srcWindow); - var multiplied = vector / vectorized_Value; - ref double currentDst = ref Unsafe.Add(ref dstRef, i); - Span dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize); - multiplied.CopyTo(dstWindow); - } - - for (; i < len; i++) - { - Unsafe.Add(ref dstRef, i) = Unsafe.Add(ref srcRef, i) / dVal; - } - } - internal static void DivideCore(this Mass dividend, ReadOnlySpan source, Span destination) - { - var dVal = dividend._Value; - int len = source.Length; - ReadOnlySpan srcDouble = MemoryMarshal.Cast(source); - Span dstDouble = MemoryMarshal.Cast(destination); - - var vectorized_Value = new Vector(dVal); - var zeroVector = Vector.Zero; // Вектор из нулей для сравнения - int vectorSize = Vector.Count; - int i = 0; - - ref double srcRef = ref MemoryMarshal.GetReference(srcDouble); - ref double dstRef = ref MemoryMarshal.GetReference(dstDouble); - - int SIMDEnd = len - (len % vectorSize); - for (; i < SIMDEnd; i += vectorSize) - { - ref double currentSrc = ref Unsafe.Add(ref srcRef, i); - ReadOnlySpan srcWindow = MemoryMarshal.CreateReadOnlySpan(ref currentSrc, vectorSize); - var vector = new Vector(srcWindow); - - // БЫСТРАЯ ПРОВЕРКА: Есть ли хотя бы один 0.0 в текущем векторе? - if (Vector.EqualsAny(vector, zeroVector)) - { - throw new DivideByZeroException($"Обнаружен делитель, равный нулю, в районе индексов {i}..{i + vectorSize - 1}."); - } - - var multiplied = vectorized_Value / vector; - ref double currentDst = ref Unsafe.Add(ref dstRef, i); - Span dstWindow = MemoryMarshal.CreateSpan(ref currentDst, vectorSize); - multiplied.CopyTo(dstWindow); - } - - // Хвостовой цикл - for (; i < len; i++) - { - double divisor = Unsafe.Add(ref srcRef, i); - if (divisor == 0.0) - { - throw new DivideByZeroException($"Обнаружен делитель, равный нулю, в индексе {i}."); - } - Unsafe.Add(ref dstRef, i) = dVal / divisor; - } - } - } - - public class PogonMassConverter : JsonConverter - { - // Используем инвариантную культуру, чтобы разделителем всегда была точка (10.5, а не 10,5) - private static readonly CultureInfo Culture = CultureInfo.InvariantCulture; - - public override PogonMass Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - double double_Value; - - if (reader.TokenType == JsonTokenType.String) - { - // Безопасно парсим double из строки с поддержкой точки как разделителя - if (!double.TryParse(reader.GetString(), NumberStyles.Float, Culture, out double_Value)) - { - throw new JsonException($"Не удалось преобразовать строковое значение в double для метрики {nameof(PogonMass)}."); - } - } - else - { - // Прямое быстрое чтение числа из JSON - double_Value = reader.GetDouble(); - } - - return new(double_Value); - } - - public override void Write(Utf8JsonWriter writer, PogonMass value, JsonSerializerOptions options) - { - // Записываем число напрямую в байтовый буфер без выделения памяти под строки - writer.WriteNumberValue(value._Value); - } - - public override void WriteAsPropertyName(Utf8JsonWriter writer, PogonMass value, JsonSerializerOptions options) - { - // Ключи JSON-объектов всегда должны быть строками. - // Форматируем double в строку с точкой, чтобы другие сервисы экосистемы прочитали её корректно. - // Формат "R" (Round-trip) гарантирует, что число не потеряет точность при обратном парсинге. - writer.WritePropertyName(value._Value.ToString("R", Culture)); - } - - public override PogonMass ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - string propertyName = reader.GetString()!; - - if (!double.TryParse(propertyName, NumberStyles.Float, Culture, out double double_Value)) - { - throw new JsonException($"Невалидное числовое значение в ключе свойства JSON: '{propertyName}' для метрики {nameof(PogonMass)}."); - } - - return new(double_Value); - } - } -} -#endif \ No newline at end of file +// // === Array === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ[] operator +// /(AAAAAAAAAAAAAAAA[] units, BBBBBBBBBBBBBBBB divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ?[] operator +// /(AAAAAAAAAAAAAAAA?[] units, BBBBBBBBBBBBBBBB divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ[] operator +// /(BBBBBBBBBBBBBBBB dividend, AAAAAAAAAAAAAAAA[] units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ?[] operator +// /(BBBBBBBBBBBBBBBB dividend, AAAAAAAAAAAAAAAA?[] units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ[] operator /(AAAAAAAAAAAAAAAA[] units, BBBBBBBBBBBBBBBB? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new ZZZZZZZZZZZZZZZZ[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ?[] operator /(AAAAAAAAAAAAAAAA?[] units, BBBBBBBBBBBBBBBB? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new ZZZZZZZZZZZZZZZZ?[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ[] operator /(BBBBBBBBBBBBBBBB? dividend, AAAAAAAAAAAAAAAA[] units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new ZZZZZZZZZZZZZZZZ[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ?[] operator /(BBBBBBBBBBBBBBBB? dividend, AAAAAAAAAAAAAAAA?[] units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new ZZZZZZZZZZZZZZZZ?[units.Length]); + +// // === List === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(List units, BBBBBBBBBBBBBBBB divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(List units, BBBBBBBBBBBBBBBB divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(BBBBBBBBBBBBBBBB dividend, List units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(BBBBBBBBBBBBBBBB dividend, List units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(List units, BBBBBBBBBBBBBBBB? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(List units, BBBBBBBBBBBBBBBB? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(BBBBBBBBBBBBBBBB? dividend, List units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(BBBBBBBBBBBBBBBB? dividend, List units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List(units.Count)); + +// // === IEnumerable === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(IEnumerable units, BBBBBBBBBBBBBBBB divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(IEnumerable units, BBBBBBBBBBBBBBBB divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(BBBBBBBBBBBBBBBB dividend, IEnumerable units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(BBBBBBBBBBBBBBBB dividend, IEnumerable units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(IEnumerable units, BBBBBBBBBBBBBBBB? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => new ZZZZZZZZZZZZZZZZ(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(IEnumerable units, BBBBBBBBBBBBBBBB? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => u is null ? (ZZZZZZZZZZZZZZZZ?)null : new ZZZZZZZZZZZZZZZZ(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(BBBBBBBBBBBBBBBB? dividend, IEnumerable units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => new ZZZZZZZZZZZZZZZZ(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(BBBBBBBBBBBBBBBB? dividend, IEnumerable units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? (ZZZZZZZZZZZZZZZZ?)null : new ZZZZZZZZZZZZZZZZ(0d))); +// } +// public readonly partial record struct AAAAAAAAAAAAAAAA +// { +// // === Array === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB[] operator +// /(ZZZZZZZZZZZZZZZZ[] units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB?[] operator +// /(ZZZZZZZZZZZZZZZZ?[] units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB[] operator +// /(AAAAAAAAAAAAAAAA dividend, ZZZZZZZZZZZZZZZZ[] units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB?[] operator +// /(AAAAAAAAAAAAAAAA dividend, ZZZZZZZZZZZZZZZZ?[] units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB[] operator /(ZZZZZZZZZZZZZZZZ[] units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new BBBBBBBBBBBBBBBB[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB?[] operator /(ZZZZZZZZZZZZZZZZ?[] units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new BBBBBBBBBBBBBBBB?[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB[] operator /(AAAAAAAAAAAAAAAA? dividend, ZZZZZZZZZZZZZZZZ[] units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new BBBBBBBBBBBBBBBB[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB?[] operator /(AAAAAAAAAAAAAAAA? dividend, ZZZZZZZZZZZZZZZZ?[] units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new BBBBBBBBBBBBBBBB?[units.Length]); + +// // === List === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(List units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(List units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(AAAAAAAAAAAAAAAA dividend, List units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(AAAAAAAAAAAAAAAA dividend, List units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(List units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(List units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(AAAAAAAAAAAAAAAA? dividend, List units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(AAAAAAAAAAAAAAAA? dividend, List units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List(units.Count)); + +// // === IEnumerable === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(IEnumerable units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(IEnumerable units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(AAAAAAAAAAAAAAAA dividend, IEnumerable units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(AAAAAAAAAAAAAAAA dividend, IEnumerable units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(IEnumerable units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => new BBBBBBBBBBBBBBBB(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(IEnumerable units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => u is null ? (BBBBBBBBBBBBBBBB?)null : new BBBBBBBBBBBBBBBB(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(AAAAAAAAAAAAAAAA? dividend, IEnumerable units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => new BBBBBBBBBBBBBBBB(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(AAAAAAAAAAAAAAAA? dividend, IEnumerable units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? (BBBBBBBBBBBBBBBB?)null : new BBBBBBBBBBBBBBBB(0d))); + + + + + + + + + +// // === Array === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ[] operator +// /(BBBBBBBBBBBBBBBB[] units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ?[] operator +// /(BBBBBBBBBBBBBBBB?[] units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ[] operator +// /(AAAAAAAAAAAAAAAA dividend, BBBBBBBBBBBBBBBB[] units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ?[] operator +// /(AAAAAAAAAAAAAAAA dividend, BBBBBBBBBBBBBBBB?[] units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ[] operator /(BBBBBBBBBBBBBBBB[] units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new ZZZZZZZZZZZZZZZZ[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ?[] operator /(BBBBBBBBBBBBBBBB?[] units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new ZZZZZZZZZZZZZZZZ?[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ[] operator /(AAAAAAAAAAAAAAAA? dividend, BBBBBBBBBBBBBBBB[] units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new ZZZZZZZZZZZZZZZZ[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ZZZZZZZZZZZZZZZZ?[] operator /(AAAAAAAAAAAAAAAA? dividend, BBBBBBBBBBBBBBBB?[] units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new ZZZZZZZZZZZZZZZZ?[units.Length]); + +// // === List === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(List units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(List units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(AAAAAAAAAAAAAAAA dividend, List units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(AAAAAAAAAAAAAAAA dividend, List units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(List units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(List units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(AAAAAAAAAAAAAAAA? dividend, List units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(AAAAAAAAAAAAAAAA? dividend, List units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List(units.Count)); + +// // === IEnumerable === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(IEnumerable units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(IEnumerable units, AAAAAAAAAAAAAAAA divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(AAAAAAAAAAAAAAAA dividend, IEnumerable units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(AAAAAAAAAAAAAAAA dividend, IEnumerable units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(IEnumerable units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => new ZZZZZZZZZZZZZZZZ(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(IEnumerable units, AAAAAAAAAAAAAAAA? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => u is null ? (ZZZZZZZZZZZZZZZZ?)null : new ZZZZZZZZZZZZZZZZ(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(AAAAAAAAAAAAAAAA? dividend, IEnumerable units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => new ZZZZZZZZZZZZZZZZ(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(AAAAAAAAAAAAAAAA? dividend, IEnumerable units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? (ZZZZZZZZZZZZZZZZ?)null : new ZZZZZZZZZZZZZZZZ(0d))); +// } +//} + +//namespace QWERTYkez.Mensura.Units.Pogon +//{ +// [JsonConverter(typeof(PogonAAAAAAAAAAAAAAAAConverter))] +// public readonly partial record struct ZZZZZZZZZZZZZZZZ : IMensuraUnit, IEquatable, IMensuraUnit +// { + +// [JsonInclude, DataMember, JsonPropertyName("v"), Obsolete] // для JSON / EF на случай сбоев, если пробелма с _Value +// internal double Value { get => _Value; init => _Value = value; } +// internal readonly double _Value; +// internal ZZZZZZZZZZZZZZZZ(double value) => _Value = value; + + +// [NotMapped, JsonIgnore] internal AAAAAAAAAAAAAAAA PerValue +// { get => (AAAAAAAAAAAAAAAA)_Value; init => _Value = (double)value; } + + + +// [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 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 AAAAAAAAAAAAAAAA operator *(ZZZZZZZZZZZZZZZZ left, BBBBBBBBBBBBBBBB right) => new(left._Value * right._Value); +// public static AAAAAAAAAAAAAAAA operator *(ZZZZZZZZZZZZZZZZ? left, BBBBBBBBBBBBBBBB right) => new(left.Protected() * right._Value); +// public static AAAAAAAAAAAAAAAA operator *(ZZZZZZZZZZZZZZZZ left, BBBBBBBBBBBBBBBB? right) => new(left._Value * right.Protected()); +// public static AAAAAAAAAAAAAAAA operator *(ZZZZZZZZZZZZZZZZ? left, BBBBBBBBBBBBBBBB? right) => new(left.Protected() * right.Protected()); + +// public static AAAAAAAAAAAAAAAA operator *(BBBBBBBBBBBBBBBB left, ZZZZZZZZZZZZZZZZ right) => new(right._Value * left._Value); +// public static AAAAAAAAAAAAAAAA operator *(BBBBBBBBBBBBBBBB? left, ZZZZZZZZZZZZZZZZ right) => new(right._Value * left.Protected()); +// public static AAAAAAAAAAAAAAAA operator *(BBBBBBBBBBBBBBBB left, ZZZZZZZZZZZZZZZZ? right) => new(right.Protected() * left._Value); +// public static AAAAAAAAAAAAAAAA operator *(BBBBBBBBBBBBBBBB? left, ZZZZZZZZZZZZZZZZ? right) => new(right.Protected() * left.Protected()); + +// public static BBBBBBBBBBBBBBBB operator /(AAAAAAAAAAAAAAAA left, ZZZZZZZZZZZZZZZZ right) => new(left._Value / right._Value); +// public static BBBBBBBBBBBBBBBB operator /(AAAAAAAAAAAAAAAA? left, ZZZZZZZZZZZZZZZZ right) => new(left.Protected() / right._Value); +// public static BBBBBBBBBBBBBBBB operator /(AAAAAAAAAAAAAAAA left, ZZZZZZZZZZZZZZZZ? right) => new(left._Value / right.Protected()); +// public static BBBBBBBBBBBBBBBB operator /(AAAAAAAAAAAAAAAA? left, ZZZZZZZZZZZZZZZZ? right) => new(left.Protected() / right.Protected()); + + + + + + + + +// // === Array === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA[] operator +// *(BBBBBBBBBBBBBBBB[] units, ZZZZZZZZZZZZZZZZ multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA?[] operator +// *(BBBBBBBBBBBBBBBB?[] units, ZZZZZZZZZZZZZZZZ multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA[] operator +// *(ZZZZZZZZZZZZZZZZ multiplicator, BBBBBBBBBBBBBBBB[] units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA?[] operator +// *(ZZZZZZZZZZZZZZZZ multiplicator, BBBBBBBBBBBBBBBB?[] units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA[] operator *(BBBBBBBBBBBBBBBB[] units, ZZZZZZZZZZZZZZZZ? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new AAAAAAAAAAAAAAAA[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA?[] operator *(BBBBBBBBBBBBBBBB?[] units, ZZZZZZZZZZZZZZZZ? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new AAAAAAAAAAAAAAAA?[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA[] operator *(ZZZZZZZZZZZZZZZZ? multiplicator, BBBBBBBBBBBBBBBB[] units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new AAAAAAAAAAAAAAAA[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static AAAAAAAAAAAAAAAA?[] operator *(ZZZZZZZZZZZZZZZZ? multiplicator, BBBBBBBBBBBBBBBB?[] units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new AAAAAAAAAAAAAAAA?[units.Length]); + +// // === List === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// *(List units, ZZZZZZZZZZZZZZZZ multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// *(List units, ZZZZZZZZZZZZZZZZ multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// *(ZZZZZZZZZZZZZZZZ multiplicator, List units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// *(ZZZZZZZZZZZZZZZZ multiplicator, List units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(List units, ZZZZZZZZZZZZZZZZ? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(List units, ZZZZZZZZZZZZZZZZ? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(ZZZZZZZZZZZZZZZZ? multiplicator, List units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator *(ZZZZZZZZZZZZZZZZ? multiplicator, List units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : new List(units.Count)); + +// // === IEnumerable === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// *(IEnumerable units, ZZZZZZZZZZZZZZZZ multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// *(IEnumerable units, ZZZZZZZZZZZZZZZZ multiplicator) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// *(ZZZZZZZZZZZZZZZZ multiplicator, IEnumerable units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// *(ZZZZZZZZZZZZZZZZ multiplicator, IEnumerable units) => units.Multiply(multiplicator._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(IEnumerable units, ZZZZZZZZZZZZZZZZ? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new AAAAAAAAAAAAAAAA(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(IEnumerable units, ZZZZZZZZZZZZZZZZ? multiplicator) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? (AAAAAAAAAAAAAAAA?)null : new AAAAAAAAAAAAAAAA(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(ZZZZZZZZZZZZZZZZ? multiplicator, IEnumerable units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => new AAAAAAAAAAAAAAAA(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator *(ZZZZZZZZZZZZZZZZ? multiplicator, IEnumerable units) => +// multiplicator.HasValue ? units * multiplicator.Value : (units is null ? null! : units.Select(u => u is null ? (AAAAAAAAAAAAAAAA?)null : new AAAAAAAAAAAAAAAA(0d))); + + + + + + +// // === Array === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB[] operator +// /(AAAAAAAAAAAAAAAA[] units, ZZZZZZZZZZZZZZZZ divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB?[] operator +// /(AAAAAAAAAAAAAAAA?[] units, ZZZZZZZZZZZZZZZZ divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB[] operator +// /(ZZZZZZZZZZZZZZZZ dividend, AAAAAAAAAAAAAAAA[] units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB?[] operator +// /(ZZZZZZZZZZZZZZZZ dividend, AAAAAAAAAAAAAAAA?[] units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB[] operator /(AAAAAAAAAAAAAAAA[] units, ZZZZZZZZZZZZZZZZ? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new BBBBBBBBBBBBBBBB[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB?[] operator /(AAAAAAAAAAAAAAAA?[] units, ZZZZZZZZZZZZZZZZ? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new BBBBBBBBBBBBBBBB?[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB[] operator /(ZZZZZZZZZZZZZZZZ? dividend, AAAAAAAAAAAAAAAA[] units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new BBBBBBBBBBBBBBBB[units.Length]); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static BBBBBBBBBBBBBBBB?[] operator /(ZZZZZZZZZZZZZZZZ? dividend, AAAAAAAAAAAAAAAA?[] units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new BBBBBBBBBBBBBBBB?[units.Length]); + +// // === List === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(List units, ZZZZZZZZZZZZZZZZ divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(List units, ZZZZZZZZZZZZZZZZ divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(ZZZZZZZZZZZZZZZZ dividend, List units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator +// /(ZZZZZZZZZZZZZZZZ dividend, List units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(List units, ZZZZZZZZZZZZZZZZ? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(List units, ZZZZZZZZZZZZZZZZ? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(ZZZZZZZZZZZZZZZZ? dividend, List units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List(units.Count)); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List operator /(ZZZZZZZZZZZZZZZZ? dividend, List units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : new List(units.Count)); + +// // === IEnumerable === +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(IEnumerable units, ZZZZZZZZZZZZZZZZ divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(IEnumerable units, ZZZZZZZZZZZZZZZZ divisor) => units.Divide(divisor._Value); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(ZZZZZZZZZZZZZZZZ dividend, IEnumerable units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator +// /(ZZZZZZZZZZZZZZZZ dividend, IEnumerable units) => dividend._Value.Divide(units); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(IEnumerable units, ZZZZZZZZZZZZZZZZ? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => new BBBBBBBBBBBBBBBB(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(IEnumerable units, ZZZZZZZZZZZZZZZZ? divisor) => +// divisor.HasValue ? units / divisor.Value : (units is null ? null! : units.Select(u => u is null ? (BBBBBBBBBBBBBBBB?)null : new BBBBBBBBBBBBBBBB(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(ZZZZZZZZZZZZZZZZ? dividend, IEnumerable units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => new BBBBBBBBBBBBBBBB(0d))); +// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable operator /(ZZZZZZZZZZZZZZZZ? dividend, IEnumerable units) => +// dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? (BBBBBBBBBBBBBBBB?)null : new BBBBBBBBBBBBBBBB(0d))); +// } + +// internal static class PogonAAAAAAAAAAAAAAAAExtensions +// { +// public static double Protected(this ZZZZZZZZZZZZZZZZ? unit) => unit is null ? 0d : unit.Value._Value; +// internal static double ToDouble(this BBBBBBBBBBBBBBBB? unit) => unit?._Value ?? 0d; +// } + +// public class PogonAAAAAAAAAAAAAAAAConverter : JsonConverter +// { +// // Используем инвариантную культуру, чтобы разделителем всегда была точка (10.5, а не 10,5) +// private static readonly CultureInfo Culture = CultureInfo.InvariantCulture; + +// public override ZZZZZZZZZZZZZZZZ Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) +// { +// double double_Value; + +// if (reader.TokenType == JsonTokenType.String) +// { +// // Безопасно парсим double из строки с поддержкой точки как разделителя +// if (!double.TryParse(reader.GetString(), NumberStyles.Float, Culture, out double_Value)) +// { +// throw new JsonException($"Не удалось преобразовать строковое значение в double для метрики {nameof(ZZZZZZZZZZZZZZZZ)}."); +// } +// } +// else +// { +// // Прямое быстрое чтение числа из JSON +// double_Value = reader.GetDouble(); +// } + +// return new(double_Value); +// } + +// public override void Write(Utf8JsonWriter writer, ZZZZZZZZZZZZZZZZ value, JsonSerializerOptions options) +// { +// // Записываем число напрямую в байтовый буфер без выделения памяти под строки +// writer.WriteNumberValue(value._Value); +// } + +// public override void WriteAsPropertyName(Utf8JsonWriter writer, ZZZZZZZZZZZZZZZZ value, JsonSerializerOptions options) +// { +// // Ключи JSON-объектов всегда должны быть строками. +// // Форматируем double в строку с точкой, чтобы другие сервисы экосистемы прочитали её корректно. +// // Формат "R" (Round-trip) гарантирует, что число не потеряет точность при обратном парсинге. +// writer.WritePropertyName(value._Value.ToString("R", Culture)); +// } + +// public override ZZZZZZZZZZZZZZZZ ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) +// { +// string propertyName = reader.GetString()!; + +// if (!double.TryParse(propertyName, NumberStyles.Float, Culture, out double double_Value)) +// { +// throw new JsonException($"Невалидное числовое значение в ключе свойства JSON: '{propertyName}' для метрики {nameof(ZZZZZZZZZZZZZZZZ)}."); +// } + +// return new(double_Value); +// } +// } +//} +//#endif \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Pogon/PogonXXXXXXXX.Ref.cs b/QWERTYkez.Mensura/Units/Pogon/PogonXXXXXXXX.Ref.cs index 27a6d20..49108c3 100644 --- a/QWERTYkez.Mensura/Units/Pogon/PogonXXXXXXXX.Ref.cs +++ b/QWERTYkez.Mensura/Units/Pogon/PogonXXXXXXXX.Ref.cs @@ -1,61 +1,65 @@ -#if DEBUG -namespace QWERTYkez.Mensura.Units.Pogon; +//#if DEBUG -public readonly partial record struct PogonMass -{ - public static PogonMass GramPerMilliMeter { get; } = new() { _PerMilliMeter = new() { Grams = 1 } }; - public static PogonMass KiloGramPerMilliMeter { get; } = new() { _PerMilliMeter = new() { KiloGrams = 1 } }; - public static PogonMass CentnerPerMilliMeter { get; } = new() { _PerMilliMeter = new() { Centners = 1 } }; - public static PogonMass TonPerMilliMeter { get; } = new() { _PerMilliMeter = new() { Tons = 1 } }; - [NotMapped, JsonIgnore] public Mass _PerMilliMeter - { get => (Mass)_Value; init => _Value = (double)value; } +//// Reference + +//namespace QWERTYkez.Mensura.Units.Pogon; + +//[ComplexUnitGenerator] +//public readonly partial record struct ZZZZZZZZZZZZZZZZ +//{ +// public static ZZZZZZZZZZZZZZZZ GramPerMilliMeter { get; } = new() { _PerMilliMeter = new() { Grams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ KiloGramPerMilliMeter { get; } = new() { _PerMilliMeter = new() { KiloGrams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ CentnerPerMilliMeter { get; } = new() { _PerMilliMeter = new() { Centners = 1 } }; +// public static ZZZZZZZZZZZZZZZZ TonPerMilliMeter { get; } = new() { _PerMilliMeter = new() { Tons = 1 } }; +// [NotMapped, JsonIgnore] public AAAAAAAAAAAAAAAA _PerMilliMeter +// { get => (AAAAAAAAAAAAAAAA)_Value; init => _Value = (double)value; } - public static PogonMass GramPerCentiMeter { get; } = new() { PerCentiMeter = new() { Grams = 1 } }; - public static PogonMass KiloGramPerCentiMeter { get; } = new() { PerCentiMeter = new() { KiloGrams = 1 } }; - public static PogonMass CentnerPerCentiMeter { get; } = new() { PerCentiMeter = new() { Centners = 1 } }; - public static PogonMass TonPerCentiMeter { get; } = new() { PerCentiMeter = new() { Tons = 1 } }; - [NotMapped, JsonIgnore] public Mass PerCentiMeter - { - get => new(_Value * LengthConv.CentiMeters.Multiplicator); - init => _Value = value._Value / LengthConv.CentiMeters.Multiplicator; - } +// public static ZZZZZZZZZZZZZZZZ GramPerCentiMeter { get; } = new() { PerCentiMeter = new() { Grams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ KiloGramPerCentiMeter { get; } = new() { PerCentiMeter = new() { KiloGrams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ CentnerPerCentiMeter { get; } = new() { PerCentiMeter = new() { Centners = 1 } }; +// public static ZZZZZZZZZZZZZZZZ TonPerCentiMeter { get; } = new() { PerCentiMeter = new() { Tons = 1 } }; +// [NotMapped, JsonIgnore] public AAAAAAAAAAAAAAAA PerCentiMeter +// { +// get => new(_Value * BBBBBBBBBBBBBBBBConv.CentiMeters.Multiplicator); +// init => _Value = value._Value / BBBBBBBBBBBBBBBBConv.CentiMeters.Multiplicator; +// } - public static PogonMass GramPerDeciMeter { get; } = new() { PerDeciMeter = new() { Grams = 1 } }; - public static PogonMass KiloGramPerDeciMeter { get; } = new() { PerDeciMeter = new() { KiloGrams = 1 } }; - public static PogonMass CentnerPerDeciMeter { get; } = new() { PerDeciMeter = new() { Centners = 1 } }; - public static PogonMass TonPerDeciMeter { get; } = new() { PerDeciMeter = new() { Tons = 1 } }; +// public static ZZZZZZZZZZZZZZZZ GramPerDeciMeter { get; } = new() { PerDeciMeter = new() { Grams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ KiloGramPerDeciMeter { get; } = new() { PerDeciMeter = new() { KiloGrams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ CentnerPerDeciMeter { get; } = new() { PerDeciMeter = new() { Centners = 1 } }; +// public static ZZZZZZZZZZZZZZZZ TonPerDeciMeter { get; } = new() { PerDeciMeter = new() { Tons = 1 } }; - [NotMapped, JsonIgnore] public Mass PerDeciMeter - { - get => new(_Value * LengthConv.DeciMeters.Multiplicator); - init => _Value = value._Value / LengthConv.DeciMeters.Multiplicator; - } +// [NotMapped, JsonIgnore] public AAAAAAAAAAAAAAAA PerDeciMeter +// { +// get => new(_Value * BBBBBBBBBBBBBBBBConv.DeciMeters.Multiplicator); +// init => _Value = value._Value / BBBBBBBBBBBBBBBBConv.DeciMeters.Multiplicator; +// } - public static PogonMass GramPerMeter { get; } = new() { PerMeter = new() { Grams = 1 } }; - public static PogonMass KiloGramPerMeter { get; } = new() { PerMeter = new() { KiloGrams = 1 } }; - public static PogonMass CentnerPerMeter { get; } = new() { PerMeter = new() { Centners = 1 } }; - public static PogonMass TonPerMeter { get; } = new() { PerMeter = new() { Tons = 1 } }; +// public static ZZZZZZZZZZZZZZZZ GramPerMeter { get; } = new() { PerMeter = new() { Grams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ KiloGramPerMeter { get; } = new() { PerMeter = new() { KiloGrams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ CentnerPerMeter { get; } = new() { PerMeter = new() { Centners = 1 } }; +// public static ZZZZZZZZZZZZZZZZ TonPerMeter { get; } = new() { PerMeter = new() { Tons = 1 } }; - [NotMapped, JsonIgnore] public Mass PerMeter - { - get => new(_Value * LengthConv.Meters.Multiplicator); - init => _Value = value._Value / LengthConv.Meters.Multiplicator; - } +// [NotMapped, JsonIgnore] public AAAAAAAAAAAAAAAA PerMeter +// { +// get => new(_Value * BBBBBBBBBBBBBBBBConv.Meters.Multiplicator); +// init => _Value = value._Value / BBBBBBBBBBBBBBBBConv.Meters.Multiplicator; +// } - public static PogonMass GramPerKiloMeter { get; } = new() { PerKiloMeter = new() { Grams = 1 } }; - public static PogonMass KiloGramPerKiloMeter { get; } = new() { PerKiloMeter = new() { KiloGrams = 1 } }; - public static PogonMass CentnerPerKiloMeter { get; } = new() { PerKiloMeter = new() { Centners = 1 } }; - public static PogonMass TonPerKiloMeter { get; } = new() { PerKiloMeter = new() { Tons = 1 } }; +// public static ZZZZZZZZZZZZZZZZ GramPerKiloMeter { get; } = new() { PerKiloMeter = new() { Grams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ KiloGramPerKiloMeter { get; } = new() { PerKiloMeter = new() { KiloGrams = 1 } }; +// public static ZZZZZZZZZZZZZZZZ CentnerPerKiloMeter { get; } = new() { PerKiloMeter = new() { Centners = 1 } }; +// public static ZZZZZZZZZZZZZZZZ TonPerKiloMeter { get; } = new() { PerKiloMeter = new() { Tons = 1 } }; - [NotMapped, JsonIgnore] public Mass PerKiloMeter - { - get => new(_Value * LengthConv.KiloMeters.Multiplicator); - init => _Value = value._Value / LengthConv.KiloMeters.Multiplicator; - } +// [NotMapped, JsonIgnore] public AAAAAAAAAAAAAAAA PerKiloMeter +// { +// get => new(_Value * BBBBBBBBBBBBBBBBConv.KiloMeters.Multiplicator); +// init => _Value = value._Value / BBBBBBBBBBBBBBBBConv.KiloMeters.Multiplicator; +// } -} -#endif \ No newline at end of file +//} +//#endif \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Pressure.cs b/QWERTYkez.Mensura/Units/Pressure.cs index 06a06ac..54d9098 100644 --- a/QWERTYkez.Mensura/Units/Pressure.cs +++ b/QWERTYkez.Mensura/Units/Pressure.cs @@ -3,20 +3,12 @@ /// /// Base value is Pascals or NewtonsPerMeterSquared /// -[UnitOperatorsGenerator, DebuggerDisplay("Pa, N/m2 = {NewtonsPerMeterSquared.ToString(\"0.###\")}, kgf/mm2 = {KiloGramForcesPerMilliMeterSquared.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("Pa, N/m2 = {NewtonsPerMeterSquared.ToString(\"0.###\")}, kgf/mm2 = {KiloGramForcesPerMilliMeterSquared.ToString(\"0.###\")}")] public readonly partial record struct Pressure { - [NotMapped, JsonIgnore] public double _Pascals { get => Pascals; init => Pascals = value; } + public static Pressure Pascal { get; } = new() { _Pascals = 1 }; + [NotMapped, JsonIgnore] public double _Pascals { get => _Value; init => _Value = value; } - public static Pressure Pascal { get; } = new() { Pascals = 1 }; - [NotMapped, JsonIgnore] public double Pascals - { - get => _Value; - init - { - _Value = value; - } - } public static Pressure NewtonPerMeterSquared { get; } = new() { NewtonsPerMeterSquared = 1 }; [NotMapped, JsonIgnore] public double NewtonsPerMeterSquared diff --git a/QWERTYkez.Mensura/Units/Speed.cs b/QWERTYkez.Mensura/Units/Speed.cs index bdca3d4..2a03450 100644 --- a/QWERTYkez.Mensura/Units/Speed.cs +++ b/QWERTYkez.Mensura/Units/Speed.cs @@ -3,20 +3,12 @@ /// /// Base value is KiloMetersPerHour /// -[UnitOperatorsGenerator, DebuggerDisplay("km/h = {_KiloMetersPerHour.ToString(\"0.###\")}, m/s = {MetersPerSecond.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("km/h = {_KiloMetersPerHour.ToString(\"0.###\")}, m/s = {MetersPerSecond.ToString(\"0.###\")}")] public readonly partial record struct Speed { - [NotMapped, JsonIgnore] public double _KiloMetersPerHour { get => KiloMetersPerHour; init => KiloMetersPerHour = value; } + public static Speed KiloMeterPerHour { get; } = new() { _KiloMetersPerHour = 1 }; + [NotMapped, JsonIgnore] public double _KiloMetersPerHour { get => _Value; init => _Value = value; } - public static Speed KiloMeterPerHour { get; } = new() { KiloMetersPerHour = 1 }; - [NotMapped, JsonIgnore] public double KiloMetersPerHour - { - get => _Value; - init - { - _Value = value; - } - } public static Speed MeterPerSecond { get; } = new() { MetersPerSecond = 1 }; [NotMapped, JsonIgnore] public double MetersPerSecond diff --git a/QWERTYkez.Mensura/Units/Time.cs b/QWERTYkez.Mensura/Units/Time.cs index 8b82f7f..d110dcd 100644 --- a/QWERTYkez.Mensura/Units/Time.cs +++ b/QWERTYkez.Mensura/Units/Time.cs @@ -3,20 +3,12 @@ /// /// Base value is MilliSeconds /// -[UnitOperatorsGenerator, DebuggerDisplay("ms = {_MilliSeconds.ToString(\"0.###\")}, s = {Seconds.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("ms = {_MilliSeconds.ToString(\"0.###\")}, s = {Seconds.ToString(\"0.###\")}")] public readonly partial record struct Time { - [NotMapped, JsonIgnore] public double _MilliSeconds { get => MilliSeconds; init => MilliSeconds = value; } + public static Time MilliSecond { get; } = new() { _MilliSeconds = 1 }; + [NotMapped, JsonIgnore] public double _MilliSeconds { get => _Value; init => _Value = value; } - public static Time MilliSecond { get; } = new() { MilliSeconds = 1 }; - [NotMapped, JsonIgnore] public double MilliSeconds - { - get => _Value; - init - { - _Value = value; - } - } public static Time Second { get; } = new() { Seconds = 1 }; [NotMapped, JsonIgnore] public double Seconds diff --git a/QWERTYkez.Mensura/Units/Torque.cs b/QWERTYkez.Mensura/Units/Torque.cs index f01b8fe..c08327b 100644 --- a/QWERTYkez.Mensura/Units/Torque.cs +++ b/QWERTYkez.Mensura/Units/Torque.cs @@ -3,20 +3,12 @@ /// /// Base value is Newton_Meters /// -[UnitOperatorsGenerator, DebuggerDisplay("N*m = {_Newton_Meters.ToString(\"0.###\")}, kgf*m = {KiloGramForce_Meters.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("N*m = {_Newton_Meters.ToString(\"0.###\")}, kgf*m = {KiloGramForce_Meters.ToString(\"0.###\")}")] public readonly partial record struct Torque { - [NotMapped, JsonIgnore] public double _Newton_Meters { get => Newton_Meters; init => Newton_Meters = value; } + public static Torque Newton_Meter { get; } = new() { _Newton_Meters = 1 }; + [NotMapped, JsonIgnore] public double _Newton_Meters { get => _Value; init => _Value = value; } - public static Torque Newton_Meter { get; } = new() { Newton_Meters = 1 }; - [NotMapped, JsonIgnore] public double Newton_Meters - { - get => _Value; - init - { - _Value = value; - } - } public static Torque KiloGramForce_Meter { get; } = new() { KiloGramForce_Meters = 1 }; [NotMapped, JsonIgnore] public double KiloGramForce_Meters diff --git a/QWERTYkez.Mensura/Units/Udel/UdelForce.cs b/QWERTYkez.Mensura/Units/Udel/UdelForce.cs deleted file mode 100644 index 4e9c314..0000000 --- a/QWERTYkez.Mensura/Units/Udel/UdelForce.cs +++ /dev/null @@ -1,16 +0,0 @@ -//namespace MetricSystem; - -//[Owned, JsonConverter(typeof(MetricFormatter)), DebuggerDisplay("N/(m*mm2) = {PerMeter_PerMilliMeterSquared._Newtons.ToString(\"0.###\")}, kgf/(m*mm2) = {PerMeter_PerMilliMeterSquared.KiloGramForces.ToString(\"0.###\")}")] -//public partial class UdelForce : Udel -//{ -// [CollectionsOperatorsGenerator] public static PogonForce operator *(Area left, UdelForce right) => right * left; - -// [CollectionsOperatorsGenerator] public static PogonForce operator *(UdelForce left, Area right) => left.MultiplyProtected(right, PogonForceCoeff); -// static readonly double PogonForceCoeff = Coefficients.MultiplyCoefficient(a => a._PerMilliMeterCubic.Value = 1, b => b._MilliMetersSquared = 1, r => r._PerMilliMeter.Value = 1); -//} - -//public partial class Volume : Metric -//{ -// [CollectionsOperatorsGenerator] public static UdelForce operator /(Force left, Volume right) => left.DivideProtected(right, UdelForceCoeff); -// static readonly double UdelForceCoeff = Coefficients.DivideCoefficient(a => a.Value = 1, b => b._MilliMetersCubic = 1, r => r._PerMilliMeterCubic.Value = 1); -//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Udel/UdelMass (Density).cs b/QWERTYkez.Mensura/Units/Udel/UdelMass (Density).cs deleted file mode 100644 index 30d4bd7..0000000 --- a/QWERTYkez.Mensura/Units/Udel/UdelMass (Density).cs +++ /dev/null @@ -1,16 +0,0 @@ -//namespace MetricSystem; - -//[Owned, JsonConverter(typeof(MetricFormatter)), DebuggerDisplay("gr/(m*mm2) = {PerMeter_PerMilliMeterSquared._Grams.ToString(\"0.###\")}, kg/(m*mm2) = {PerMeter_PerMilliMeterSquared.KiloGrams.ToString(\"0.###\")}")] -//public partial class Density : Udel -//{ -// [CollectionsOperatorsGenerator] public static PogonMass operator *(Area left, Density right) => right * left; - -// [CollectionsOperatorsGenerator] public static PogonMass operator *(Density left, Area right) => left.MultiplyProtected(right, PogonMassCoeff); -// static readonly double PogonMassCoeff = Coefficients.MultiplyCoefficient(a => a._PerMilliMeterCubic.Value = 1, b => b._MilliMetersSquared = 1, r => r._PerMilliMeter.Value = 1); -//} - -//public partial class Volume : Metric -//{ -// [CollectionsOperatorsGenerator] public static Density operator /(Mass left, Volume right) => left.DivideProtected(right, DensityCoeff); -// static readonly double DensityCoeff = Coefficients.DivideCoefficient(a => a.Value = 1, b => b._MilliMetersCubic = 1, r => r._PerMilliMeterCubic.Value = 1); -//} \ No newline at end of file diff --git a/QWERTYkez.Mensura/Units/Voltage.cs b/QWERTYkez.Mensura/Units/Voltage.cs index 360e640..1e93a08 100644 --- a/QWERTYkez.Mensura/Units/Voltage.cs +++ b/QWERTYkez.Mensura/Units/Voltage.cs @@ -3,20 +3,12 @@ /// /// Base value is Volts /// -[UnitOperatorsGenerator, DebuggerDisplay("V = {_Volts.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("V = {_Volts.ToString(\"0.###\")}")] public readonly partial record struct Voltage { - [NotMapped, JsonIgnore] public double _Volts { get => Volts; init => Volts = value; } + public static Voltage Volt { get; } = new() { _Volts = 1 }; + [NotMapped, JsonIgnore] public double _Volts { get => _Value; init => _Value = value; } - public static Voltage Volt { get; } = new() { Volts = 1 }; - [NotMapped, JsonIgnore] public double Volts - { - get => _Value; - init - { - _Value = value; - } - } public static Voltage KiloVolt { get; } = new() { KiloVolts = 1 }; [NotMapped, JsonIgnore] public double KiloVolts diff --git a/QWERTYkez.Mensura/Units/Volume.cs b/QWERTYkez.Mensura/Units/Volume.cs index a8d2d3c..8ac83fb 100644 --- a/QWERTYkez.Mensura/Units/Volume.cs +++ b/QWERTYkez.Mensura/Units/Volume.cs @@ -3,20 +3,12 @@ /// /// Base value is MilliMetersCubic /// -[UnitOperatorsGenerator, DebuggerDisplay("mm3 = {_MilliMetersCubic.ToString(\"0.###\")}, m3 = {MetersCubic.ToString(\"0.###\")}")] +[UnitGenerator, DebuggerDisplay("mm3 = {_MilliMetersCubic.ToString(\"0.###\")}, m3 = {MetersCubic.ToString(\"0.###\")}")] public readonly partial record struct Volume { - [NotMapped, JsonIgnore] public double _MilliMetersCubic { get => MilliMetersCubic; init => MilliMetersCubic = value; } + public static Volume MilliMeterCubic { get; } = new() { _MilliMetersCubic = 1 }; + [NotMapped, JsonIgnore] public double _MilliMetersCubic { get => _Value; init => _Value = value; } - public static Volume MilliMeterCubic { get; } = new() { MilliMetersCubic = 1 }; - [NotMapped, JsonIgnore] public double MilliMetersCubic - { - get => _Value; - init - { - _Value = value; - } - } public static Volume CentiMeterCubic { get; } = new() { CentiMetersCubic = 1 }; [NotMapped, JsonIgnore] public double CentiMetersCubic diff --git a/QWERTYkez.Mensura/globals.cs b/QWERTYkez.Mensura/globals.cs index 27b3634..fd61be9 100644 --- a/QWERTYkez.Mensura/globals.cs +++ b/QWERTYkez.Mensura/globals.cs @@ -12,4 +12,5 @@ global using System.Text.Json; global using System.Text.Json.Serialization; global using QWERTYkez.Mensura; global using QWERTYkez.Mensura.Extensions; -global using QWERTYkez.Mensura.Units; \ No newline at end of file +global using QWERTYkez.Mensura.Units; +global using QWERTYkez.Mensura.Units.Complex; \ No newline at end of file