namespace G; [Generator] public class UnitGenerator : IIncrementalGenerator { private const string AttributeName = "UnitGenerator"; public void Initialize(IncrementalGeneratorInitializationContext context) { // Генерируем атрибут context.RegisterPostInitializationOutput(ctx => { string attributeSource = @" namespace QWERTYkez.Mensura { [System.AttributeUsage(System.AttributeTargets.Struct, AllowMultiple = false)] internal sealed class UnitGeneratorAttribute : System.Attribute { } }"; ctx.AddSource(".UnitGeneratorAttribute.g.cs", SourceText.From(attributeSource, Encoding.UTF8)); }); // Ищем все 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(); context.RegisterSourceOutput(structsProvider, (spc, structs) => { // Сначала генерируем сами структуры (Ваш оригинальный код без изменений) foreach (var structInfo in structs) { string generatedCode = GeneratePartial(structInfo); spc.AddSource($"{structInfo.TypeName}.g.cs", SourceText.From(generatedCode, Encoding.UTF8)); } // --- ТОТ САМЫЙ КОД УСЛОВНОЙ ГЕНЕРАЦИИ БИНДЕРА --- bool isMainAssembly = false; var firstStruct = structs.FirstOrDefault(); if (firstStruct.TypeName != 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 AddGeneratedConverters(System.Collections.IList converters)"); sb.AppendLine(" {"); foreach (var structInfo in structs) { sb.AppendLine($" converters.Add(new QWERTYkez.Mensura.MensuraBinder.NewtonsoftRegistrar.NewtonsoftUnitConverter());"); } sb.AppendLine(" }"); sb.AppendLine("}"); spc.AddSource(".Units.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; // Проверяем наличие атрибута [UnitGenerator] 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; return new StructInfo(namespaceName, typeSymbol.Name); } private static string GeneratePartial(StructInfo info) { string typeName = info.TypeName; string ns = info.Namespace; // Здесь должен быть полный код из вашего файла XXXXXXXXXXXX.cs // с заменой {typeName} на {typeName}. Для краткости приведён скелет. // Вы должны скопировать сюда всё содержимое вашего второго файла, // заменив {typeName} на {typeName}. string skeleton = @" global using {typeName}Extensions = QWERTYkez.Mensura.Units.{typeName}Extensions; global using {typeName} = QWERTYkez.Mensura.Units.{typeName}; using System.Runtime.Serialization; namespace QWERTYkez.Mensura.Units; [JsonConverter(typeof(UnitJsonConverter<{typeName}>))] public readonly partial record struct {typeName} : IMensuraUnit<{typeName}>, IEquatable<{typeName}>, IMensuraUnit { [JsonInclude, DataMember, JsonPropertyName(""v""), Obsolete] // для JSON / EF на случай сбоев, если пробелма с _Value internal double Value { get => _Value; init => _Value = value; } internal readonly double _Value; internal {typeName}(double value) => _Value = value; public override int GetHashCode() => _Value.GetHashCode(); public int CompareTo({typeName}? other) => _Value.CompareTo(other is null ? 0d : other.Value._Value); public int CompareTo({typeName} other) => _Value.CompareTo(other._Value); public bool Equals({typeName}? other) => _Value.Equals(other?._Value); public static explicit operator {typeName}(double val) => Unsafe.As(ref val); public static explicit operator double({typeName} unit) => unit._Value; [MethodImpl(MethodImplOptions.AggressiveInlining)] public {typeName} Abs() => new(Math.Abs(_Value)); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal R Pow2_Internal() where R : struct, IMensuraUnit, IEquatable => (_Value * _Value).ToUnit(); [MethodImpl(MethodImplOptions.AggressiveInlining)] internal R Sqrt_Internal() where R : struct, IMensuraUnit, IEquatable => Math.Sqrt(_Value).ToUnit(); [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 {typeName} Zero { get; } = new(0d); public static {typeName} Min { get; } = new(double.MinValue); public static {typeName} Max { get; } = new(double.MaxValue); public static {typeName} NegativeInfinity { get; } = new(double.NegativeInfinity); public static {typeName} PositiveInfinity { get; } = new(double.PositiveInfinity); public static bool operator ==({typeName}? T1, {typeName}? T2) => T1.Protected() == T2.Protected(); public static bool operator !=({typeName}? T1, {typeName}? T2) => T1.Protected() != T2.Protected(); public static bool operator <({typeName}? T1, {typeName}? T2) => T1.Protected() < T2.Protected(); public static bool operator <=({typeName}? T1, {typeName}? T2) => T1.Protected() <= T2.Protected(); public static bool operator >({typeName}? T1, {typeName}? T2) => T1.Protected() > T2.Protected(); public static bool operator >=({typeName}? T1, {typeName}? T2) => T1.Protected() >= T2.Protected(); public static {typeName} operator +({typeName} T2) => new(+T2._Value); public static {typeName} operator +({typeName} T1, {typeName} T2) => new(T1._Value + T2._Value); public static {typeName} operator -({typeName} T2) => new(-T2._Value); public static {typeName} operator -({typeName} T1, {typeName} T2) => new(T1._Value - T2._Value); // double public static {typeName} operator *({typeName} T1, double T2) => new(T1._Value * T2); public static {typeName} operator *({typeName} T1, double? T2) => T1 * (T2 ?? 0d); public static {typeName} operator *(double T1, {typeName} T2) => new(T1 * T2._Value); public static {typeName} operator *(double? T1, {typeName} T2) => (T1 ?? 0d) * T2; public static {typeName} operator /({typeName} T1, double T2) => new(T1._Value / T2); public static {typeName} operator /({typeName} T1, double? T2) => T1 / (T2 ?? 0d); public static double operator /({typeName} T1, {typeName} T2) => T1._Value / T2._Value; // sbyte public static {typeName} operator *({typeName} T1, sbyte T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, sbyte? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(sbyte T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(sbyte? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, sbyte T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, sbyte? T2) => T1 / T2.ToDouble(); // short public static {typeName} operator *({typeName} T1, short T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, short? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(short T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(short? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, short T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, short? T2) => T1 / T2.ToDouble(); // int public static {typeName} operator *({typeName} T1, int T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, int? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(int T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(int? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, int T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, int? T2) => T1 / T2.ToDouble(); // long public static {typeName} operator *({typeName} T1, long T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, long? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(long T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(long? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, long T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, long? T2) => T1 / T2.ToDouble(); // byte public static {typeName} operator *({typeName} T1, byte T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, byte? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(byte T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(byte? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, byte T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, byte? T2) => T1 / T2.ToDouble(); // ushort public static {typeName} operator *({typeName} T1, ushort T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, ushort? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(ushort T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(ushort? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, ushort T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, ushort? T2) => T1 / T2.ToDouble(); // uint public static {typeName} operator *({typeName} T1, uint T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, uint? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(uint T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(uint? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, uint T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, uint? T2) => T1 / T2.ToDouble(); // ulong public static {typeName} operator *({typeName} T1, ulong T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, ulong? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(ulong T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(ulong? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, ulong T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, ulong? T2) => T1 / T2.ToDouble(); // nint public static {typeName} operator *({typeName} T1, nint T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, nint? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(nint T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(nint? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, nint T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, nint? T2) => T1 / T2.ToDouble(); // nuint public static {typeName} operator *({typeName} T1, nuint T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, nuint? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(nuint T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(nuint? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, nuint T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, nuint? T2) => T1 / T2.ToDouble(); // float public static {typeName} operator *({typeName} T1, float T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, float? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(float T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(float? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, float T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, float? T2) => T1 / T2.ToDouble(); // decimal public static {typeName} operator *({typeName} T1, decimal T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, decimal? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(decimal T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(decimal? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, decimal T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, decimal? T2) => T1 / T2.ToDouble(); #if NET7_0_OR_GREATER // Int128 public static {typeName} operator *({typeName} T1, Int128 T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, Int128? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(Int128 T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(Int128? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, Int128 T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, Int128? T2) => T1 / T2.ToDouble(); // UInt128 public static {typeName} operator *({typeName} T1, UInt128 T2) => T1 * T2.ToDouble(); public static {typeName} operator *({typeName} T1, UInt128? T2) => T1 * T2.ToDouble(); public static {typeName} operator *(UInt128 T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator *(UInt128? T1, {typeName} T2) => T1.ToDouble() * T2; public static {typeName} operator /({typeName} T1, UInt128 T2) => T1 / T2.ToDouble(); public static {typeName} operator /({typeName} T1, UInt128? T2) => T1 / T2.ToDouble(); #endif } public static class {typeName}Extensions { internal static double Protected(this {typeName}? unit) => unit is null ? 0d : unit.Value._Value; // === ReadOnlySpan [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ReadOnlySpan<{typeName}> units, double divisor, Span<{typeName}> destination) => units.Div<{typeName}>(divisor, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ReadOnlySpan<{typeName}?> units, double divisor, Span<{typeName}?> destination) => units.Div<{typeName}>(divisor, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend, ReadOnlySpan<{typeName}> units, Span<{typeName}> destination) => dividend.Div<{typeName}>(units, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend, ReadOnlySpan<{typeName}?> units, Span<{typeName}?> destination) => dividend.Div<{typeName}>(units, destination); // === Array === [MethodImpl(MethodImplOptions.AggressiveInlining)]public static {typeName}[] Div( this {typeName}[] units, double divisor) => units.Div<{typeName}>(divisor); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}?[] Div( this {typeName}?[] units, double divisor) => units.Div<{typeName}>(divisor); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}[] Div( this double dividend, {typeName}[] units) => dividend.Div<{typeName}>(units); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}?[] Div( this double dividend, {typeName}?[] units) => dividend.Div<{typeName}>(units); // === List === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}> Div( this List<{typeName}> units, double divisor) => units.Div<{typeName}>(divisor); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}?> Div( this List<{typeName}?> units, double divisor) => units.Div<{typeName}>(divisor); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}> Div( this double dividend, List<{typeName}> units) => dividend.Div<{typeName}>(units); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}?> Div( this double dividend, List<{typeName}?> units) => dividend.Div<{typeName}>(units); // === ICollection === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ICollection<{typeName}> units, double divisor, Span<{typeName}> destination) => units.Div<{typeName}>(divisor, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this ICollection<{typeName}?> units, double divisor, Span<{typeName}?> destination) => units.Div<{typeName}>(divisor, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend, ICollection<{typeName}> units, Span<{typeName}> destination) => dividend.Div<{typeName}>(units, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend, ICollection<{typeName}?> units, Span<{typeName}?> destination) => dividend.Div<{typeName}>(units, destination); // === IReadOnlyCollection === [MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Div(this IReadOnlyCollection<{typeName}> units, double divisor, Span<{typeName}> destination) => units.Div<{typeName}>(divisor, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Div(this IReadOnlyCollection<{typeName}?> units, double divisor, Span<{typeName}?> destination) => units.Div<{typeName}>(divisor, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend, IReadOnlyCollection<{typeName}> units, Span<{typeName}> destination) => dividend.Div<{typeName}>(units, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Div(this double dividend, IReadOnlyCollection<{typeName}?> units, Span<{typeName}?> destination) => dividend.Div<{typeName}>(units, destination); // === IEnumerable === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}> Div( this IEnumerable<{typeName}> units, double divisor) => units.Div<{typeName}>(divisor); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}?> Div( this IEnumerable<{typeName}?> units, double divisor) => units.Div<{typeName}>(divisor); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}> Div( this double dividend, IEnumerable<{typeName}> units) => dividend.Div<{typeName}>(units); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}?> Div( this double dividend, IEnumerable<{typeName}?> units) => dividend.Div<{typeName}>(units); // === ReadOnlySpan [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this ReadOnlySpan<{typeName}> units, double subtrahend, Span<{typeName}> destination) => units.Minus<{typeName}>(subtrahend, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this ReadOnlySpan<{typeName}?> units, double subtrahend, Span<{typeName}?> destination) => units.Minus<{typeName}>(subtrahend, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend, ReadOnlySpan<{typeName}> units, Span<{typeName}> destination) => minuend.Minus<{typeName}>(units, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend, ReadOnlySpan<{typeName}?> units, Span<{typeName}?> destination) => minuend.Minus<{typeName}>(units, destination); // === Array === [MethodImpl(MethodImplOptions.AggressiveInlining)]public static {typeName}[] Minus( this {typeName}[] units, double subtrahend) => units.Minus<{typeName}>(subtrahend); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}?[] Minus( this {typeName}?[] units, double subtrahend) => units.Minus<{typeName}>(subtrahend); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}[] Minus( this double minuend, {typeName}[] units) => minuend.Minus<{typeName}>(units); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}?[] Minus( this double minuend, {typeName}?[] units) => minuend.Minus<{typeName}>(units); // === List === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}> Minus( this List<{typeName}> units, double subtrahend) => units.Minus<{typeName}>(subtrahend); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}?> Minus( this List<{typeName}?> units, double subtrahend) => units.Minus<{typeName}>(subtrahend); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}> Minus( this double minuend, List<{typeName}> units) => minuend.Minus<{typeName}>(units); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}?> Minus( this double minuend, List<{typeName}?> units) => minuend.Minus<{typeName}>(units); // === ICollection === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this ICollection<{typeName}> units, double subtrahend, Span<{typeName}> destination) => units.Minus<{typeName}>(subtrahend, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this ICollection<{typeName}?> units, double subtrahend, Span<{typeName}?> destination) => units.Minus<{typeName}>(subtrahend, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend, ICollection<{typeName}> units, Span<{typeName}> destination) => minuend.Minus<{typeName}>(units, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend, ICollection<{typeName}?> units, Span<{typeName}?> destination) => minuend.Minus<{typeName}>(units, destination); // === IReadOnlyCollection === [MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Minus(this IReadOnlyCollection<{typeName}> units, double subtrahend, Span<{typeName}> destination) => units.Minus<{typeName}>(subtrahend, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Minus(this IReadOnlyCollection<{typeName}?> units, double subtrahend, Span<{typeName}?> destination) => units.Minus<{typeName}>(subtrahend, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend, IReadOnlyCollection<{typeName}> units, Span<{typeName}> destination) => minuend.Minus<{typeName}>(units, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Minus(this double minuend, IReadOnlyCollection<{typeName}?> units, Span<{typeName}?> destination) => minuend.Minus<{typeName}>(units, destination); // === IEnumerable === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}> Minus( this IEnumerable<{typeName}> units, double subtrahend) => units.Minus<{typeName}>(subtrahend); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}?> Minus( this IEnumerable<{typeName}?> units, double subtrahend) => units.Minus<{typeName}>(subtrahend); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}> Minus( this double minuend, IEnumerable<{typeName}> units) => minuend.Minus<{typeName}>(units); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}?> Minus( this double minuend, IEnumerable<{typeName}?> units) => minuend.Minus<{typeName}>(units); // === ReadOnlySpan [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this ReadOnlySpan<{typeName}> units, double multiplicator, Span<{typeName}> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this ReadOnlySpan<{typeName}?> units, double multiplicator, Span<{typeName}?> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator, ReadOnlySpan<{typeName}> units, Span<{typeName}> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator, ReadOnlySpan<{typeName}?> units, Span<{typeName}?> destination) => units.Mul<{typeName}>(multiplicator, destination); // === Array === [MethodImpl(MethodImplOptions.AggressiveInlining)]public static {typeName}[] Mul( this {typeName}[] units, double multiplicator) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}?[] Mul( this {typeName}?[] units, double multiplicator) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}[] Mul( this double multiplicator, {typeName}[] units) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}?[] Mul( this double multiplicator, {typeName}?[] units) => units.Mul<{typeName}>(multiplicator); // === List === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}> Mul( this List<{typeName}> units, double multiplicator) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}?> Mul( this List<{typeName}?> units, double multiplicator) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}> Mul( this double multiplicator, List<{typeName}> units) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}?> Mul( this double multiplicator, List<{typeName}?> units) => units.Mul<{typeName}>(multiplicator); // === ICollection === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this ICollection<{typeName}> units, double multiplicator, Span<{typeName}> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this ICollection<{typeName}?> units, double multiplicator, Span<{typeName}?> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator, ICollection<{typeName}> units, Span<{typeName}> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator, ICollection<{typeName}?> units, Span<{typeName}?> destination) => units.Mul<{typeName}>(multiplicator, destination); // === IReadOnlyCollection === [MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Mul(this IReadOnlyCollection<{typeName}> units, double multiplicator, Span<{typeName}> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Mul(this IReadOnlyCollection<{typeName}?> units, double multiplicator, Span<{typeName}?> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator, IReadOnlyCollection<{typeName}> units, Span<{typeName}> destination) => units.Mul<{typeName}>(multiplicator, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Mul(this double multiplicator, IReadOnlyCollection<{typeName}?> units, Span<{typeName}?> destination) => units.Mul<{typeName}>(multiplicator, destination); // === IEnumerable === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}> Mul( this IEnumerable<{typeName}> units, double multiplicator) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}?> Mul( this IEnumerable<{typeName}?> units, double multiplicator) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}> Mul( this double multiplicator, IEnumerable<{typeName}> units) => units.Mul<{typeName}>(multiplicator); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}?> Mul( this double multiplicator, IEnumerable<{typeName}?> units) => units.Mul<{typeName}>(multiplicator); // === ReadOnlySpan [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this ReadOnlySpan<{typeName}> units, double summand, Span<{typeName}> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this ReadOnlySpan<{typeName}?> units, double summand, Span<{typeName}?> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand, ReadOnlySpan<{typeName}> units, Span<{typeName}> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand, ReadOnlySpan<{typeName}?> units, Span<{typeName}?> destination) => units.Plus<{typeName}>(summand, destination); // === Array === [MethodImpl(MethodImplOptions.AggressiveInlining)]public static {typeName}[] Plus( this {typeName}[] units, double summand) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}?[] Plus( this {typeName}?[] units, double summand) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}[] Plus( this double summand, {typeName}[] units) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeName}?[] Plus( this double summand, {typeName}?[] units) => units.Plus<{typeName}>(summand); // === List === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}> Plus( this List<{typeName}> units, double summand) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}?> Plus( this List<{typeName}?> units, double summand) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}> Plus( this double summand, List<{typeName}> units) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeName}?> Plus( this double summand, List<{typeName}?> units) => units.Plus<{typeName}>(summand); // === ICollection === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this ICollection<{typeName}> units, double summand, Span<{typeName}> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this ICollection<{typeName}?> units, double summand, Span<{typeName}?> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand, ICollection<{typeName}> units, Span<{typeName}> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand, ICollection<{typeName}?> units, Span<{typeName}?> destination) => units.Plus<{typeName}>(summand, destination); // === IReadOnlyCollection === [MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Plus(this IReadOnlyCollection<{typeName}> units, double summand, Span<{typeName}> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)]public static void Plus(this IReadOnlyCollection<{typeName}?> units, double summand, Span<{typeName}?> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand, IReadOnlyCollection<{typeName}> units, Span<{typeName}> destination) => units.Plus<{typeName}>(summand, destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Plus(this double summand, IReadOnlyCollection<{typeName}?> units, Span<{typeName}?> destination) => units.Plus<{typeName}>(summand, destination); // === IEnumerable === [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}> Plus( this IEnumerable<{typeName}> units, double summand) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}?> Plus( this IEnumerable<{typeName}?> units, double summand) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}> Plus( this double summand, IEnumerable<{typeName}> units) => units.Plus<{typeName}>(summand); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeName}?> Plus( this double summand, IEnumerable<{typeName}?> units) => units.Plus<{typeName}>(summand); // Sum Average Max Min (не nullable) ========================================== // === ReadOnlySpan === SIMD public static {typeName} Sum(this ReadOnlySpan<{typeName}> units) => AggregateUnitExtensions.Sum(units); public static {typeName} Average(this ReadOnlySpan<{typeName}> units) => AggregateUnitExtensions.Average(units); public static {typeName} Max(this ReadOnlySpan<{typeName}> units) => AggregateUnitExtensions.Max(units); public static {typeName} Min(this ReadOnlySpan<{typeName}> units) => AggregateUnitExtensions.Min(units); // === List === public static {typeName} Sum(this List<{typeName}> list) => AggregateUnitExtensions.Sum(list); public static {typeName} Average(this List<{typeName}> list) => AggregateUnitExtensions.Average(list); public static {typeName} Max(this List<{typeName}> list) => AggregateUnitExtensions.Max(list); public static {typeName} Min(this List<{typeName}> list) => AggregateUnitExtensions.Min(list); // === ICollection === public static {typeName} Sum(this ICollection<{typeName}> collection) => AggregateUnitExtensions.Sum(collection); public static {typeName} Average(this ICollection<{typeName}> collection) => AggregateUnitExtensions.Average(collection); public static {typeName} Max(this ICollection<{typeName}> collection) => AggregateUnitExtensions.Max(collection); public static {typeName} Min(this ICollection<{typeName}> collection) => AggregateUnitExtensions.Min(collection); // === IReadOnlyCollection === public static {typeName} Sum(this IReadOnlyCollection<{typeName}> collection) => AggregateUnitExtensions.Sum(collection); public static {typeName} Average(this IReadOnlyCollection<{typeName}> collection) => AggregateUnitExtensions.Average(collection); public static {typeName} Max(this IReadOnlyCollection<{typeName}> collection) => AggregateUnitExtensions.Max(collection); public static {typeName} Min(this IReadOnlyCollection<{typeName}> collection) => AggregateUnitExtensions.Min(collection); // === IEnumerable === public static {typeName} Sum(this IEnumerable<{typeName}> collection) => AggregateUnitExtensions.Sum(collection); public static {typeName} Average(this IEnumerable<{typeName}> collection) => AggregateUnitExtensions.Average(collection); public static {typeName} Max(this IEnumerable<{typeName}> collection) => AggregateUnitExtensions.Max(collection); public static {typeName} Min(this IEnumerable<{typeName}> collection) => AggregateUnitExtensions.Min(collection); // Sum Average Max Min (nullable) ========================================== // === ReadOnlySpan === public static {typeName} Sum(this ReadOnlySpan<{typeName}?> units) => AggregateUnitExtensions.Sum(units); public static {typeName} Average(this ReadOnlySpan<{typeName}?> units) => AggregateUnitExtensions.Average(units); public static {typeName} Max(this ReadOnlySpan<{typeName}?> units) => AggregateUnitExtensions.Max(units); public static {typeName} Min(this ReadOnlySpan<{typeName}?> units) => AggregateUnitExtensions.Min(units); // === List === public static {typeName} Sum(this List<{typeName}?> list) => AggregateUnitExtensions.Sum(list); public static {typeName} Average(this List<{typeName}?> list) => AggregateUnitExtensions.Average(list); public static {typeName} Max(this List<{typeName}?> list) => AggregateUnitExtensions.Max(list); public static {typeName} Min(this List<{typeName}?> list) => AggregateUnitExtensions.Min(list); // === ICollection === public static {typeName} Sum(this ICollection<{typeName}?> collection) => AggregateUnitExtensions.Sum(collection); public static {typeName} Average(this ICollection<{typeName}?> collection) => AggregateUnitExtensions.Average(collection); public static {typeName} Max(this ICollection<{typeName}?> collection) => AggregateUnitExtensions.Max(collection); public static {typeName} Min(this ICollection<{typeName}?> collection) => AggregateUnitExtensions.Min(collection); // === IReadOnlyCollection === public static {typeName} Sum(this IReadOnlyCollection<{typeName}?> collection) => AggregateUnitExtensions.Sum(collection); public static {typeName} Average(this IReadOnlyCollection<{typeName}?> collection) => AggregateUnitExtensions.Average(collection); public static {typeName} Max(this IReadOnlyCollection<{typeName}?> collection) => AggregateUnitExtensions.Max(collection); public static {typeName} Min(this IReadOnlyCollection<{typeName}?> collection) => AggregateUnitExtensions.Min(collection); // === IEnumerable === public static {typeName} Sum(this IEnumerable<{typeName}?> collection) => AggregateUnitExtensions.Sum(collection); public static {typeName} Average(this IEnumerable<{typeName}?> collection) => AggregateUnitExtensions.Average(collection); public static {typeName} Max(this IEnumerable<{typeName}?> collection) => AggregateUnitExtensions.Max(collection); public static {typeName} Min(this IEnumerable<{typeName}?> collection) => AggregateUnitExtensions.Min(collection); } "; return skeleton.Replace("{typeName}", typeName).Replace("{ns}", ns); } private readonly struct StructInfo(string ns, string name) { public string Namespace { get; } = ns; public string TypeName { get; } = name; } }