Files
QWERTYkez.Mensura/QWERTYkez.Mensura.Generator/ComplexUnitGenerator.cs
melekhin 6765aa23b1 Tests
2026-06-09 16:45:22 +07:00

945 lines
73 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace 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)]
internal 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));
}
// --- ТОТ САМЫЙ КОД УСЛОВНОЙ ГЕНЕРАЦИИ БИНДЕРА ---
bool isMainAssembly = false;
var firstStruct = structs.FirstOrDefault();
if (firstStruct.TypeNameZ != null)
{
// Если пространство имен содержит "Tests", флаг останется false
if (firstStruct.Namespace.StartsWith("QWERTYkez.Mensura") && !firstStruct.Namespace.Contains("Tests"))
{
isMainAssembly = true;
}
}
// Генерируем файл ТОЛЬКО для основного проекта
if (isMainAssembly)
{
var sb = new StringBuilder();
sb.AppendLine("namespace QWERTYkez.Mensura;");
sb.AppendLine("internal static partial class MensuraBinder");
sb.AppendLine("{");
sb.AppendLine(" [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]");
sb.AppendLine(" static partial void AddGeneratedComplexConverters(System.Collections.IList converters)");
sb.AppendLine(" {");
foreach (var structInfo in structs)
{
sb.AppendLine($" converters.Add(new QWERTYkez.Mensura.MensuraBinder.NewtonsoftRegistrar.NewtonsoftUnitConverter<QWERTYkez.Mensura.Units.{structInfo.TypeNameZ}>());");
}
sb.AppendLine(" }");
sb.AppendLine("}");
spc.AddSource(".ComplexUnits.MensuraBinder.g.cs", SourceText.From(sb.ToString(), 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.{typeNameZ}Extensions;
global using {typeNameZ} = QWERTYkez.Mensura.Units.{typeNameZ};
using System.Globalization;
using System.Runtime.Serialization;
namespace QWERTYkez.Mensura.Units;
[JsonConverter(typeof(UnitJsonConverter<{typeNameZ}>))]
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, IgnoreDataMember] internal {typeNameA} PerValue
{ get => ({typeNameA})_Value; init => _Value = (double)value; }
public static explicit operator {typeNameZ}(double val) => Unsafe.As<double, {typeNameZ}>(ref val);
public static explicit operator double({typeNameZ} unit) => unit._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.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator
*({typeNameB}?[] units, {typeNameZ} multiplicator) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator
*({typeNameZ} multiplicator, {typeNameB}[] units) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator
*({typeNameZ} multiplicator, {typeNameB}?[] units) => units.Mul<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator
*(List<{typeNameB}> units, {typeNameZ} multiplicator) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator
*(List<{typeNameB}?> units, {typeNameZ} multiplicator) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator
*({typeNameZ} multiplicator, List<{typeNameB}> units) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator
*({typeNameZ} multiplicator, List<{typeNameB}?> units) => units.Mul<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator
*(IEnumerable<{typeNameB}> units, {typeNameZ} multiplicator) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator
*(IEnumerable<{typeNameB}?> units, {typeNameZ} multiplicator) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator
*({typeNameZ} multiplicator, IEnumerable<{typeNameB}> units) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator
*({typeNameZ} multiplicator, IEnumerable<{typeNameB}?> units) => units.Mul<{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.Div<{typeNameA}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator
/({typeNameA}?[] units, {typeNameZ} divisor) => units.Div<{typeNameA}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator
/({typeNameZ} dividend, {typeNameA}[] units) => dividend._Value.Div<{typeNameA}, {typeNameB}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator
/({typeNameZ} dividend, {typeNameA}?[] units) => dividend._Value.Div<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator
/(List<{typeNameA}> units, {typeNameZ} divisor) => units.Div<{typeNameA}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator
/(List<{typeNameA}?> units, {typeNameZ} divisor) => units.Div<{typeNameA}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator
/({typeNameZ} dividend, List<{typeNameA}> units) => dividend._Value.Div<{typeNameA}, {typeNameB}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator
/({typeNameZ} dividend, List<{typeNameA}?> units) => dividend._Value.Div<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator
/(IEnumerable<{typeNameA}> units, {typeNameZ} divisor) => units.Div<{typeNameA}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator
/(IEnumerable<{typeNameA}?> units, {typeNameZ} divisor) => units.Div<{typeNameA}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator
/({typeNameZ} dividend, IEnumerable<{typeNameA}> units) => dividend._Value.Div<{typeNameA}, {typeNameB}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator
/({typeNameZ} dividend, IEnumerable<{typeNameA}?> units) => dividend._Value.Div<{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)));
}
public static class {typeNameZ}Extensions
{
internal static double Protected(this {typeNameZ}? unit) => unit is null ? 0d : unit.Value._Value;
internal static double ToDouble(this {typeNameB}? unit) => unit?._Value ?? 0d;
// === ReadOnlySpan
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ReadOnlySpan<{typeNameZ}> units,
double divisor, Span<{typeNameZ}> destination) => units.Div<{typeNameZ}>(divisor, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ReadOnlySpan<{typeNameZ}?> units,
double divisor, Span<{typeNameZ}?> destination) => units.Div<{typeNameZ}>(divisor, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend,
ReadOnlySpan<{typeNameZ}> units, Span<{typeNameZ}> destination) => dividend.Div<{typeNameZ}>(units, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend,
ReadOnlySpan<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => dividend.Div<{typeNameZ}>(units, destination);
// === Array ===
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static {typeNameZ}[] Div(
this {typeNameZ}[] units, double divisor) => units.Div<{typeNameZ}>(divisor);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] Div(
this {typeNameZ}?[] units, double divisor) => units.Div<{typeNameZ}>(divisor);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] Div(
this double dividend, {typeNameZ}[] units) => dividend.Div<{typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] Div(
this double dividend, {typeNameZ}?[] units) => dividend.Div<{typeNameZ}>(units);
// === List<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> Div(
this List<{typeNameZ}> units, double divisor) => units.Div<{typeNameZ}>(divisor);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> Div(
this List<{typeNameZ}?> units, double divisor) => units.Div<{typeNameZ}>(divisor);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> Div(
this double dividend, List<{typeNameZ}> units) => dividend.Div<{typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> Div(
this double dividend, List<{typeNameZ}?> units) => dividend.Div<{typeNameZ}>(units);
// === ICollection<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ICollection<{typeNameZ}> units,
double divisor, Span<{typeNameZ}> destination) => units.Div<{typeNameZ}>(divisor, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ICollection<{typeNameZ}?> units,
double divisor, Span<{typeNameZ}?> destination) => units.Div<{typeNameZ}>(divisor, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend,
ICollection<{typeNameZ}> units, Span<{typeNameZ}> destination) => dividend.Div<{typeNameZ}>(units, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend,
ICollection<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => dividend.Div<{typeNameZ}>(units, destination);
// === IReadOnlyCollection<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Div(this IReadOnlyCollection<{typeNameZ}> units,
double divisor, Span<{typeNameZ}> destination) => units.Div<{typeNameZ}>(divisor, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Div(this IReadOnlyCollection<{typeNameZ}?> units,
double divisor, Span<{typeNameZ}?> destination) => units.Div<{typeNameZ}>(divisor, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend,
IReadOnlyCollection<{typeNameZ}> units, Span<{typeNameZ}> destination) => dividend.Div<{typeNameZ}>(units, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend,
IReadOnlyCollection<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => dividend.Div<{typeNameZ}>(units, destination);
// === IEnumerable<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> Div(
this IEnumerable<{typeNameZ}> units, double divisor) => units.Div<{typeNameZ}>(divisor);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> Div(
this IEnumerable<{typeNameZ}?> units, double divisor) => units.Div<{typeNameZ}>(divisor);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> Div(
this double dividend, IEnumerable<{typeNameZ}> units) => dividend.Div<{typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> Div(
this double dividend, IEnumerable<{typeNameZ}?> units) => dividend.Div<{typeNameZ}>(units);
// === ReadOnlySpan
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this ReadOnlySpan<{typeNameZ}> units,
double subtrahend, Span<{typeNameZ}> destination) => units.Minus<{typeNameZ}>(subtrahend, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this ReadOnlySpan<{typeNameZ}?> units,
double subtrahend, Span<{typeNameZ}?> destination) => units.Minus<{typeNameZ}>(subtrahend, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend,
ReadOnlySpan<{typeNameZ}> units, Span<{typeNameZ}> destination) => minuend.Minus<{typeNameZ}>(units, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend,
ReadOnlySpan<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => minuend.Minus<{typeNameZ}>(units, destination);
// === Array ===
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static {typeNameZ}[] Minus(
this {typeNameZ}[] units, double subtrahend) => units.Minus<{typeNameZ}>(subtrahend);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] Minus(
this {typeNameZ}?[] units, double subtrahend) => units.Minus<{typeNameZ}>(subtrahend);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] Minus(
this double minuend, {typeNameZ}[] units) => minuend.Minus<{typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] Minus(
this double minuend, {typeNameZ}?[] units) => minuend.Minus<{typeNameZ}>(units);
// === List<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> Minus(
this List<{typeNameZ}> units, double subtrahend) => units.Minus<{typeNameZ}>(subtrahend);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> Minus(
this List<{typeNameZ}?> units, double subtrahend) => units.Minus<{typeNameZ}>(subtrahend);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> Minus(
this double minuend, List<{typeNameZ}> units) => minuend.Minus<{typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> Minus(
this double minuend, List<{typeNameZ}?> units) => minuend.Minus<{typeNameZ}>(units);
// === ICollection<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this ICollection<{typeNameZ}> units,
double subtrahend, Span<{typeNameZ}> destination) => units.Minus<{typeNameZ}>(subtrahend, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this ICollection<{typeNameZ}?> units,
double subtrahend, Span<{typeNameZ}?> destination) => units.Minus<{typeNameZ}>(subtrahend, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend,
ICollection<{typeNameZ}> units, Span<{typeNameZ}> destination) => minuend.Minus<{typeNameZ}>(units, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend,
ICollection<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => minuend.Minus<{typeNameZ}>(units, destination);
// === IReadOnlyCollection<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Minus(this IReadOnlyCollection<{typeNameZ}> units,
double subtrahend, Span<{typeNameZ}> destination) => units.Minus<{typeNameZ}>(subtrahend, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Minus(this IReadOnlyCollection<{typeNameZ}?> units,
double subtrahend, Span<{typeNameZ}?> destination) => units.Minus<{typeNameZ}>(subtrahend, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend,
IReadOnlyCollection<{typeNameZ}> units, Span<{typeNameZ}> destination) => minuend.Minus<{typeNameZ}>(units, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend,
IReadOnlyCollection<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => minuend.Minus<{typeNameZ}>(units, destination);
// === IEnumerable<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> Minus(
this IEnumerable<{typeNameZ}> units, double subtrahend) => units.Minus<{typeNameZ}>(subtrahend);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> Minus(
this IEnumerable<{typeNameZ}?> units, double subtrahend) => units.Minus<{typeNameZ}>(subtrahend);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> Minus(
this double minuend, IEnumerable<{typeNameZ}> units) => minuend.Minus<{typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> Minus(
this double minuend, IEnumerable<{typeNameZ}?> units) => minuend.Minus<{typeNameZ}>(units);
// === ReadOnlySpan
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this ReadOnlySpan<{typeNameZ}> units,
double multiplicator, Span<{typeNameZ}> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this ReadOnlySpan<{typeNameZ}?> units,
double multiplicator, Span<{typeNameZ}?> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator,
ReadOnlySpan<{typeNameZ}> units, Span<{typeNameZ}> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator,
ReadOnlySpan<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
// === Array ===
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static {typeNameZ}[] Mul(
this {typeNameZ}[] units, double multiplicator) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] Mul(
this {typeNameZ}?[] units, double multiplicator) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] Mul(
this double multiplicator, {typeNameZ}[] units) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] Mul(
this double multiplicator, {typeNameZ}?[] units) => units.Mul<{typeNameZ}>(multiplicator);
// === List<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> Mul(
this List<{typeNameZ}> units, double multiplicator) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> Mul(
this List<{typeNameZ}?> units, double multiplicator) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> Mul(
this double multiplicator, List<{typeNameZ}> units) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> Mul(
this double multiplicator, List<{typeNameZ}?> units) => units.Mul<{typeNameZ}>(multiplicator);
// === ICollection<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this ICollection<{typeNameZ}> units,
double multiplicator, Span<{typeNameZ}> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this ICollection<{typeNameZ}?> units,
double multiplicator, Span<{typeNameZ}?> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator,
ICollection<{typeNameZ}> units, Span<{typeNameZ}> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator,
ICollection<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
// === IReadOnlyCollection<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Mul(this IReadOnlyCollection<{typeNameZ}> units,
double multiplicator, Span<{typeNameZ}> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Mul(this IReadOnlyCollection<{typeNameZ}?> units,
double multiplicator, Span<{typeNameZ}?> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator,
IReadOnlyCollection<{typeNameZ}> units, Span<{typeNameZ}> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator,
IReadOnlyCollection<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => units.Mul<{typeNameZ}>(multiplicator, destination);
// === IEnumerable<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> Mul(
this IEnumerable<{typeNameZ}> units, double multiplicator) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> Mul(
this IEnumerable<{typeNameZ}?> units, double multiplicator) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> Mul(
this double multiplicator, IEnumerable<{typeNameZ}> units) => units.Mul<{typeNameZ}>(multiplicator);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> Mul(
this double multiplicator, IEnumerable<{typeNameZ}?> units) => units.Mul<{typeNameZ}>(multiplicator);
// === ReadOnlySpan
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this ReadOnlySpan<{typeNameZ}> units,
double summand, Span<{typeNameZ}> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this ReadOnlySpan<{typeNameZ}?> units,
double summand, Span<{typeNameZ}?> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand,
ReadOnlySpan<{typeNameZ}> units, Span<{typeNameZ}> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand,
ReadOnlySpan<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => units.Plus<{typeNameZ}>(summand, destination);
// === Array ===
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static {typeNameZ}[] Plus(
this {typeNameZ}[] units, double summand) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] Plus(
this {typeNameZ}?[] units, double summand) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] Plus(
this double summand, {typeNameZ}[] units) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] Plus(
this double summand, {typeNameZ}?[] units) => units.Plus<{typeNameZ}>(summand);
// === List<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> Plus(
this List<{typeNameZ}> units, double summand) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> Plus(
this List<{typeNameZ}?> units, double summand) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> Plus(
this double summand, List<{typeNameZ}> units) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> Plus(
this double summand, List<{typeNameZ}?> units) => units.Plus<{typeNameZ}>(summand);
// === ICollection<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this ICollection<{typeNameZ}> units,
double summand, Span<{typeNameZ}> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this ICollection<{typeNameZ}?> units,
double summand, Span<{typeNameZ}?> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand,
ICollection<{typeNameZ}> units, Span<{typeNameZ}> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand,
ICollection<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => units.Plus<{typeNameZ}>(summand, destination);
// === IReadOnlyCollection<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Plus(this IReadOnlyCollection<{typeNameZ}> units,
double summand, Span<{typeNameZ}> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Plus(this IReadOnlyCollection<{typeNameZ}?> units,
double summand, Span<{typeNameZ}?> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand,
IReadOnlyCollection<{typeNameZ}> units, Span<{typeNameZ}> destination) => units.Plus<{typeNameZ}>(summand, destination);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand,
IReadOnlyCollection<{typeNameZ}?> units, Span<{typeNameZ}?> destination) => units.Plus<{typeNameZ}>(summand, destination);
// === IEnumerable<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> Plus(
this IEnumerable<{typeNameZ}> units, double summand) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> Plus(
this IEnumerable<{typeNameZ}?> units, double summand) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> Plus(
this double summand, IEnumerable<{typeNameZ}> units) => units.Plus<{typeNameZ}>(summand);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> Plus(
this double summand, IEnumerable<{typeNameZ}?> units) => units.Plus<{typeNameZ}>(summand);
// Sum Average Max Min (не nullable) ==========================================
// === ReadOnlySpan === SIMD
public static {typeNameZ} Sum(this ReadOnlySpan<{typeNameZ}> units) => AggregateUnitExtensions.Sum(units);
public static {typeNameZ} Average(this ReadOnlySpan<{typeNameZ}> units) => AggregateUnitExtensions.Average(units);
public static {typeNameZ} Max(this ReadOnlySpan<{typeNameZ}> units) => AggregateUnitExtensions.Max(units);
public static {typeNameZ} Min(this ReadOnlySpan<{typeNameZ}> units) => AggregateUnitExtensions.Min(units);
// === List<T> ===
public static {typeNameZ} Sum(this List<{typeNameZ}> list) => AggregateUnitExtensions.Sum(list);
public static {typeNameZ} Average(this List<{typeNameZ}> list) => AggregateUnitExtensions.Average(list);
public static {typeNameZ} Max(this List<{typeNameZ}> list) => AggregateUnitExtensions.Max(list);
public static {typeNameZ} Min(this List<{typeNameZ}> list) => AggregateUnitExtensions.Min(list);
// === ICollection<T> ===
public static {typeNameZ} Sum(this ICollection<{typeNameZ}> collection) => AggregateUnitExtensions.Sum(collection);
public static {typeNameZ} Average(this ICollection<{typeNameZ}> collection) => AggregateUnitExtensions.Average(collection);
public static {typeNameZ} Max(this ICollection<{typeNameZ}> collection) => AggregateUnitExtensions.Max(collection);
public static {typeNameZ} Min(this ICollection<{typeNameZ}> collection) => AggregateUnitExtensions.Min(collection);
// === IReadOnlyCollection<T> ===
public static {typeNameZ} Sum(this IReadOnlyCollection<{typeNameZ}> collection) => AggregateUnitExtensions.Sum(collection);
public static {typeNameZ} Average(this IReadOnlyCollection<{typeNameZ}> collection) => AggregateUnitExtensions.Average(collection);
public static {typeNameZ} Max(this IReadOnlyCollection<{typeNameZ}> collection) => AggregateUnitExtensions.Max(collection);
public static {typeNameZ} Min(this IReadOnlyCollection<{typeNameZ}> collection) => AggregateUnitExtensions.Min(collection);
// === IEnumerable<T> ===
public static {typeNameZ} Sum(this IEnumerable<{typeNameZ}> collection) => AggregateUnitExtensions.Sum(collection);
public static {typeNameZ} Average(this IEnumerable<{typeNameZ}> collection) => AggregateUnitExtensions.Average(collection);
public static {typeNameZ} Max(this IEnumerable<{typeNameZ}> collection) => AggregateUnitExtensions.Max(collection);
public static {typeNameZ} Min(this IEnumerable<{typeNameZ}> collection) => AggregateUnitExtensions.Min(collection);
// Sum Average Max Min (nullable) ==========================================
// === ReadOnlySpan ===
public static {typeNameZ} Sum(this ReadOnlySpan<{typeNameZ}?> units) => AggregateUnitExtensions.Sum(units);
public static {typeNameZ} Average(this ReadOnlySpan<{typeNameZ}?> units) => AggregateUnitExtensions.Average(units);
public static {typeNameZ} Max(this ReadOnlySpan<{typeNameZ}?> units) => AggregateUnitExtensions.Max(units);
public static {typeNameZ} Min(this ReadOnlySpan<{typeNameZ}?> units) => AggregateUnitExtensions.Min(units);
// === List<T> ===
public static {typeNameZ} Sum(this List<{typeNameZ}?> list) => AggregateUnitExtensions.Sum(list);
public static {typeNameZ} Average(this List<{typeNameZ}?> list) => AggregateUnitExtensions.Average(list);
public static {typeNameZ} Max(this List<{typeNameZ}?> list) => AggregateUnitExtensions.Max(list);
public static {typeNameZ} Min(this List<{typeNameZ}?> list) => AggregateUnitExtensions.Min(list);
// === ICollection<T> ===
public static {typeNameZ} Sum(this ICollection<{typeNameZ}?> collection) => AggregateUnitExtensions.Sum(collection);
public static {typeNameZ} Average(this ICollection<{typeNameZ}?> collection) => AggregateUnitExtensions.Average(collection);
public static {typeNameZ} Max(this ICollection<{typeNameZ}?> collection) => AggregateUnitExtensions.Max(collection);
public static {typeNameZ} Min(this ICollection<{typeNameZ}?> collection) => AggregateUnitExtensions.Min(collection);
// === IReadOnlyCollection<T> ===
public static {typeNameZ} Sum(this IReadOnlyCollection<{typeNameZ}?> collection) => AggregateUnitExtensions.Sum(collection);
public static {typeNameZ} Average(this IReadOnlyCollection<{typeNameZ}?> collection) => AggregateUnitExtensions.Average(collection);
public static {typeNameZ} Max(this IReadOnlyCollection<{typeNameZ}?> collection) => AggregateUnitExtensions.Max(collection);
public static {typeNameZ} Min(this IReadOnlyCollection<{typeNameZ}?> collection) => AggregateUnitExtensions.Min(collection);
// === IEnumerable<T> ===
public static {typeNameZ} Sum(this IEnumerable<{typeNameZ}?> collection) => AggregateUnitExtensions.Sum(collection);
public static {typeNameZ} Average(this IEnumerable<{typeNameZ}?> collection) => AggregateUnitExtensions.Average(collection);
public static {typeNameZ} Max(this IEnumerable<{typeNameZ}?> collection) => AggregateUnitExtensions.Max(collection);
public static {typeNameZ} Min(this IEnumerable<{typeNameZ}?> collection) => AggregateUnitExtensions.Min(collection);
}
public readonly partial record struct {typeNameA}
{
// === Array ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator
/({typeNameZ}[] units, {typeNameA} divisor) => units.Div<{typeNameZ}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator
/({typeNameZ}?[] units, {typeNameA} divisor) => units.Div<{typeNameZ}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator
/({typeNameA} dividend, {typeNameZ}[] units) => dividend._Value.Div<{typeNameZ}, {typeNameB}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator
/({typeNameA} dividend, {typeNameZ}?[] units) => dividend._Value.Div<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator
/(List<{typeNameZ}> units, {typeNameA} divisor) => units.Div<{typeNameZ}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator
/(List<{typeNameZ}?> units, {typeNameA} divisor) => units.Div<{typeNameZ}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator
/({typeNameA} dividend, List<{typeNameZ}> units) => dividend._Value.Div<{typeNameZ}, {typeNameB}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}?> operator
/({typeNameA} dividend, List<{typeNameZ}?> units) => dividend._Value.Div<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator
/(IEnumerable<{typeNameZ}> units, {typeNameA} divisor) => units.Div<{typeNameZ}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator
/(IEnumerable<{typeNameZ}?> units, {typeNameA} divisor) => units.Div<{typeNameZ}, {typeNameB}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator
/({typeNameA} dividend, IEnumerable<{typeNameZ}> units) => dividend._Value.Div<{typeNameZ}, {typeNameB}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}?> operator
/({typeNameA} dividend, IEnumerable<{typeNameZ}?> units) => dividend._Value.Div<{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.Div<{typeNameB}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator
/({typeNameB}?[] units, {typeNameA} divisor) => units.Div<{typeNameB}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator
/({typeNameA} dividend, {typeNameB}[] units) => dividend._Value.Div<{typeNameB}, {typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator
/({typeNameA} dividend, {typeNameB}?[] units) => dividend._Value.Div<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator
/(List<{typeNameB}> units, {typeNameA} divisor) => units.Div<{typeNameB}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator
/(List<{typeNameB}?> units, {typeNameA} divisor) => units.Div<{typeNameB}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator
/({typeNameA} dividend, List<{typeNameB}> units) => dividend._Value.Div<{typeNameB}, {typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator
/({typeNameA} dividend, List<{typeNameB}?> units) => dividend._Value.Div<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator
/(IEnumerable<{typeNameB}> units, {typeNameA} divisor) => units.Div<{typeNameB}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator
/(IEnumerable<{typeNameB}?> units, {typeNameA} divisor) => units.Div<{typeNameB}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator
/({typeNameA} dividend, IEnumerable<{typeNameB}> units) => dividend._Value.Div<{typeNameB}, {typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator
/({typeNameA} dividend, IEnumerable<{typeNameB}?> units) => dividend._Value.Div<{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)));
}
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.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator
*({typeNameZ}?[] units, {typeNameB} multiplicator) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator
*({typeNameB} multiplicator, {typeNameZ}[] units) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator
*({typeNameB} multiplicator, {typeNameZ}?[] units) => units.Mul<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator
*(List<{typeNameZ}> units, {typeNameB} multiplicator) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator
*(List<{typeNameZ}?> units, {typeNameB} multiplicator) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator
*({typeNameB} multiplicator, List<{typeNameZ}> units) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}?> operator
*({typeNameB} multiplicator, List<{typeNameZ}?> units) => units.Mul<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator
*(IEnumerable<{typeNameZ}> units, {typeNameB} multiplicator) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator
*(IEnumerable<{typeNameZ}?> units, {typeNameB} multiplicator) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator
*({typeNameB} multiplicator, IEnumerable<{typeNameZ}> units) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}?> operator
*({typeNameB} multiplicator, IEnumerable<{typeNameZ}?> units) => units.Mul<{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.Div<{typeNameA}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator
/({typeNameA}?[] units, {typeNameB} divisor) => units.Div<{typeNameA}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator
/({typeNameB} dividend, {typeNameA}[] units) => dividend._Value.Div<{typeNameA}, {typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator
/({typeNameB} dividend, {typeNameA}?[] units) => dividend._Value.Div<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator
/(List<{typeNameA}> units, {typeNameB} divisor) => units.Div<{typeNameA}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator
/(List<{typeNameA}?> units, {typeNameB} divisor) => units.Div<{typeNameA}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator
/({typeNameB} dividend, List<{typeNameA}> units) => dividend._Value.Div<{typeNameA}, {typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}?> operator
/({typeNameB} dividend, List<{typeNameA}?> units) => dividend._Value.Div<{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<T> ===
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator
/(IEnumerable<{typeNameA}> units, {typeNameB} divisor) => units.Div<{typeNameA}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator
/(IEnumerable<{typeNameA}?> units, {typeNameB} divisor) => units.Div<{typeNameA}, {typeNameZ}>(divisor._Value);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator
/({typeNameB} dividend, IEnumerable<{typeNameA}> units) => dividend._Value.Div<{typeNameA}, {typeNameZ}>(units);
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}?> operator
/({typeNameB} dividend, IEnumerable<{typeNameA}?> units) => dividend._Value.Div<{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)));
}
";
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;
}
}