Tests
This commit is contained in:
@@ -1,10 +1,4 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System.Text;
|
||||
|
||||
namespace G;
|
||||
namespace G;
|
||||
|
||||
[Generator]
|
||||
public class ComplexUnitGenerator : IIncrementalGenerator
|
||||
@@ -20,7 +14,7 @@ public class ComplexUnitGenerator : IIncrementalGenerator
|
||||
namespace QWERTYkez.Mensura
|
||||
{
|
||||
[System.AttributeUsage(System.AttributeTargets.Struct, AllowMultiple = false)]
|
||||
public sealed class ComplexUnitGeneratorAttribute : System.Attribute
|
||||
internal sealed class ComplexUnitGeneratorAttribute : System.Attribute
|
||||
{
|
||||
public string TypeNameA { get; }
|
||||
public string TypeNameB { get; }
|
||||
@@ -49,12 +43,45 @@ namespace QWERTYkez.Mensura
|
||||
// 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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,7 +176,7 @@ using System.Runtime.Serialization;
|
||||
|
||||
namespace QWERTYkez.Mensura.Units;
|
||||
|
||||
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftUnitConverter<{typeNameZ}>)), JsonConverter(typeof(UnitJsonConverter<{typeNameZ}>))]
|
||||
[JsonConverter(typeof(UnitJsonConverter<{typeNameZ}>))]
|
||||
public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, IEquatable<{typeNameZ}>, IMensuraUnit
|
||||
{
|
||||
|
||||
@@ -202,13 +229,13 @@ public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, I
|
||||
|
||||
// === Array ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator
|
||||
*({typeNameB}[] units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*({typeNameB}[] units, {typeNameZ} multiplicator) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator
|
||||
*({typeNameB}?[] units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*({typeNameB}?[] units, {typeNameZ} multiplicator) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator
|
||||
*({typeNameZ} multiplicator, {typeNameB}[] units) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*({typeNameZ} multiplicator, {typeNameB}[] units) => units.Mul<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator
|
||||
*({typeNameZ} multiplicator, {typeNameB}?[] units) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*({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) =>
|
||||
@@ -220,13 +247,13 @@ public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, I
|
||||
|
||||
// === List<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator
|
||||
*(List<{typeNameB}> units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*(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.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*(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.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*({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.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*({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) =>
|
||||
@@ -238,13 +265,13 @@ public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, I
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator
|
||||
*(IEnumerable<{typeNameB}> units, {typeNameZ} multiplicator) => units.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*(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.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*(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.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*({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.Multiply<{typeNameB}, {typeNameA}>(multiplicator._Value);
|
||||
*({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) =>
|
||||
@@ -261,13 +288,13 @@ public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, I
|
||||
|
||||
// === Array ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator
|
||||
/({typeNameA}[] units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value);
|
||||
/({typeNameA}[] units, {typeNameZ} divisor) => units.Div<{typeNameA}, {typeNameB}>(divisor._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator
|
||||
/({typeNameA}?[] units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value);
|
||||
/({typeNameA}?[] units, {typeNameZ} divisor) => units.Div<{typeNameA}, {typeNameB}>(divisor._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator
|
||||
/({typeNameZ} dividend, {typeNameA}[] units) => dividend._Value.Divide<{typeNameA}, {typeNameB}>(units);
|
||||
/({typeNameZ} dividend, {typeNameA}[] units) => dividend._Value.Div<{typeNameA}, {typeNameB}>(units);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator
|
||||
/({typeNameZ} dividend, {typeNameA}?[] units) => dividend._Value.Divide<{typeNameA}, {typeNameB}>(units);
|
||||
/({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) =>
|
||||
@@ -279,13 +306,13 @@ public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, I
|
||||
|
||||
// === List<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator
|
||||
/(List<{typeNameA}> units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value);
|
||||
/(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.Divide<{typeNameA}, {typeNameB}>(divisor._Value);
|
||||
/(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.Divide<{typeNameA}, {typeNameB}>(units);
|
||||
/({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.Divide<{typeNameA}, {typeNameB}>(units);
|
||||
/({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) =>
|
||||
@@ -297,13 +324,13 @@ public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, I
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator
|
||||
/(IEnumerable<{typeNameA}> units, {typeNameZ} divisor) => units.Divide<{typeNameA}, {typeNameB}>(divisor._Value);
|
||||
/(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.Divide<{typeNameA}, {typeNameB}>(divisor._Value);
|
||||
/(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.Divide<{typeNameA}, {typeNameB}>(units);
|
||||
/({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.Divide<{typeNameA}, {typeNameB}>(units);
|
||||
/({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) =>
|
||||
@@ -314,23 +341,357 @@ public readonly partial record struct {typeNameZ} : IMensuraUnit<{typeNameZ}>, I
|
||||
dividend.HasValue ? units / dividend.Value : (units is null ? null! : units.Select(u => u is null ? ({typeNameB}?)null : new {typeNameB}(0d)));
|
||||
}
|
||||
|
||||
internal static class {typeNameZ}Extensions
|
||||
public static class {typeNameZ}Extensions
|
||||
{
|
||||
public static double Protected(this {typeNameZ}? unit) => unit is null ? 0d : unit.Value._Value;
|
||||
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.Divide<{typeNameZ}, {typeNameB}>(divisor._Value);
|
||||
/({typeNameZ}[] units, {typeNameA} divisor) => units.Div<{typeNameZ}, {typeNameB}>(divisor._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator
|
||||
/({typeNameZ}?[] units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value);
|
||||
/({typeNameZ}?[] units, {typeNameA} divisor) => units.Div<{typeNameZ}, {typeNameB}>(divisor._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}[] operator
|
||||
/({typeNameA} dividend, {typeNameZ}[] units) => dividend._Value.Divide<{typeNameZ}, {typeNameB}>(units);
|
||||
/({typeNameA} dividend, {typeNameZ}[] units) => dividend._Value.Div<{typeNameZ}, {typeNameB}>(units);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameB}?[] operator
|
||||
/({typeNameA} dividend, {typeNameZ}?[] units) => dividend._Value.Divide<{typeNameZ}, {typeNameB}>(units);
|
||||
/({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) =>
|
||||
@@ -342,13 +703,13 @@ public readonly partial record struct {typeNameA}
|
||||
|
||||
// === List<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameB}> operator
|
||||
/(List<{typeNameZ}> units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value);
|
||||
/(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.Divide<{typeNameZ}, {typeNameB}>(divisor._Value);
|
||||
/(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.Divide<{typeNameZ}, {typeNameB}>(units);
|
||||
/({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.Divide<{typeNameZ}, {typeNameB}>(units);
|
||||
/({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) =>
|
||||
@@ -360,13 +721,13 @@ public readonly partial record struct {typeNameA}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameB}> operator
|
||||
/(IEnumerable<{typeNameZ}> units, {typeNameA} divisor) => units.Divide<{typeNameZ}, {typeNameB}>(divisor._Value);
|
||||
/(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.Divide<{typeNameZ}, {typeNameB}>(divisor._Value);
|
||||
/(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.Divide<{typeNameZ}, {typeNameB}>(units);
|
||||
/({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.Divide<{typeNameZ}, {typeNameB}>(units);
|
||||
/({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) =>
|
||||
@@ -386,13 +747,13 @@ public readonly partial record struct {typeNameA}
|
||||
|
||||
// === Array ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator
|
||||
/({typeNameB}[] units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value);
|
||||
/({typeNameB}[] units, {typeNameA} divisor) => units.Div<{typeNameB}, {typeNameZ}>(divisor._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator
|
||||
/({typeNameB}?[] units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value);
|
||||
/({typeNameB}?[] units, {typeNameA} divisor) => units.Div<{typeNameB}, {typeNameZ}>(divisor._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator
|
||||
/({typeNameA} dividend, {typeNameB}[] units) => dividend._Value.Divide<{typeNameB}, {typeNameZ}>(units);
|
||||
/({typeNameA} dividend, {typeNameB}[] units) => dividend._Value.Div<{typeNameB}, {typeNameZ}>(units);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator
|
||||
/({typeNameA} dividend, {typeNameB}?[] units) => dividend._Value.Divide<{typeNameB}, {typeNameZ}>(units);
|
||||
/({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) =>
|
||||
@@ -404,13 +765,13 @@ public readonly partial record struct {typeNameA}
|
||||
|
||||
// === List<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator
|
||||
/(List<{typeNameB}> units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value);
|
||||
/(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.Divide<{typeNameB}, {typeNameZ}>(divisor._Value);
|
||||
/(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.Divide<{typeNameB}, {typeNameZ}>(units);
|
||||
/({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.Divide<{typeNameB}, {typeNameZ}>(units);
|
||||
/({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) =>
|
||||
@@ -422,13 +783,13 @@ public readonly partial record struct {typeNameA}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator
|
||||
/(IEnumerable<{typeNameB}> units, {typeNameA} divisor) => units.Divide<{typeNameB}, {typeNameZ}>(divisor._Value);
|
||||
/(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.Divide<{typeNameB}, {typeNameZ}>(divisor._Value);
|
||||
/(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.Divide<{typeNameB}, {typeNameZ}>(units);
|
||||
/({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.Divide<{typeNameB}, {typeNameZ}>(units);
|
||||
/({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) =>
|
||||
@@ -449,13 +810,13 @@ public readonly partial record struct {typeNameB}
|
||||
|
||||
// === Array ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator
|
||||
*({typeNameZ}[] units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*({typeNameZ}[] units, {typeNameB} multiplicator) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator
|
||||
*({typeNameZ}?[] units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*({typeNameZ}?[] units, {typeNameB} multiplicator) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}[] operator
|
||||
*({typeNameB} multiplicator, {typeNameZ}[] units) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*({typeNameB} multiplicator, {typeNameZ}[] units) => units.Mul<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameA}?[] operator
|
||||
*({typeNameB} multiplicator, {typeNameZ}?[] units) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*({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) =>
|
||||
@@ -467,13 +828,13 @@ public readonly partial record struct {typeNameB}
|
||||
|
||||
// === List<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameA}> operator
|
||||
*(List<{typeNameZ}> units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*(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.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*(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.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*({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.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*({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) =>
|
||||
@@ -485,13 +846,13 @@ public readonly partial record struct {typeNameB}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameA}> operator
|
||||
*(IEnumerable<{typeNameZ}> units, {typeNameB} multiplicator) => units.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*(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.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*(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.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*({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.Multiply<{typeNameZ}, {typeNameA}>(multiplicator._Value);
|
||||
*({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) =>
|
||||
@@ -511,13 +872,13 @@ public readonly partial record struct {typeNameB}
|
||||
|
||||
// === Array ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator
|
||||
/({typeNameA}[] units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value);
|
||||
/({typeNameA}[] units, {typeNameB} divisor) => units.Div<{typeNameA}, {typeNameZ}>(divisor._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator
|
||||
/({typeNameA}?[] units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value);
|
||||
/({typeNameA}?[] units, {typeNameB} divisor) => units.Div<{typeNameA}, {typeNameZ}>(divisor._Value);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}[] operator
|
||||
/({typeNameB} dividend, {typeNameA}[] units) => dividend._Value.Divide<{typeNameA}, {typeNameZ}>(units);
|
||||
/({typeNameB} dividend, {typeNameA}[] units) => dividend._Value.Div<{typeNameA}, {typeNameZ}>(units);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static {typeNameZ}?[] operator
|
||||
/({typeNameB} dividend, {typeNameA}?[] units) => dividend._Value.Divide<{typeNameA}, {typeNameZ}>(units);
|
||||
/({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) =>
|
||||
@@ -529,13 +890,13 @@ public readonly partial record struct {typeNameB}
|
||||
|
||||
// === List<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static List<{typeNameZ}> operator
|
||||
/(List<{typeNameA}> units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value);
|
||||
/(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.Divide<{typeNameA}, {typeNameZ}>(divisor._Value);
|
||||
/(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.Divide<{typeNameA}, {typeNameZ}>(units);
|
||||
/({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.Divide<{typeNameA}, {typeNameZ}>(units);
|
||||
/({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) =>
|
||||
@@ -547,13 +908,13 @@ public readonly partial record struct {typeNameB}
|
||||
|
||||
// === IEnumerable<T> ===
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static IEnumerable<{typeNameZ}> operator
|
||||
/(IEnumerable<{typeNameA}> units, {typeNameB} divisor) => units.Divide<{typeNameA}, {typeNameZ}>(divisor._Value);
|
||||
/(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.Divide<{typeNameA}, {typeNameZ}>(divisor._Value);
|
||||
/(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.Divide<{typeNameA}, {typeNameZ}>(units);
|
||||
/({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.Divide<{typeNameA}, {typeNameZ}>(units);
|
||||
/({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) =>
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace G
|
||||
namespace G
|
||||
{
|
||||
[Generator(LanguageNames.CSharp)]
|
||||
public class OperatorsGenerator : IIncrementalGenerator
|
||||
@@ -16,7 +9,7 @@ using System;
|
||||
namespace QWERTYkez.Mensura
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class OperatorsGeneratorAttribute : Attribute
|
||||
internal sealed class OperatorsGeneratorAttribute : Attribute
|
||||
{
|
||||
public string CoeffName { get; }
|
||||
|
||||
@@ -158,16 +151,16 @@ namespace {info.Namespace};
|
||||
|
||||
public readonly partial record struct {info.LeftType}
|
||||
{{
|
||||
public static {info.ReturnType}[] operator *({info.LeftType} left, {info.RightType}[] right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Multiply<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static List<{info.ReturnType}> operator *({info.LeftType} left, List<{info.RightType}> right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Multiply<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static IEnumerable<{info.ReturnType}> operator *({info.LeftType} left, IEnumerable<{info.RightType}> right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Multiply<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static {info.ReturnType}[] operator *({info.LeftType} left, {info.RightType}[] right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Mul<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static List<{info.ReturnType}> operator *({info.LeftType} left, List<{info.RightType}> right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Mul<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static IEnumerable<{info.ReturnType}> operator *({info.LeftType} left, IEnumerable<{info.RightType}> right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Mul<{info.RightType}, {info.ReturnType}>(right);
|
||||
}}
|
||||
|
||||
public readonly partial record struct {info.RightType}
|
||||
{{
|
||||
public static {info.ReturnType}[] operator *({info.LeftType}[] left, {info.RightType} right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * right._Value)" : "right._Value")}.Multiply<{info.LeftType}, {info.ReturnType}>(left);
|
||||
public static List<{info.ReturnType}> operator *(List<{info.LeftType}> left, {info.RightType} right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * right._Value)" : "right._Value")}.Multiply<{info.LeftType}, {info.ReturnType}>(left);
|
||||
public static IEnumerable<{info.ReturnType}> operator *(IEnumerable<{info.LeftType}> left, {info.RightType} right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * right._Value)" : "right._Value")}.Multiply<{info.LeftType}, {info.ReturnType}>(left);
|
||||
public static {info.ReturnType}[] operator *({info.LeftType}[] left, {info.RightType} right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * right._Value)" : "right._Value")}.Mul<{info.LeftType}, {info.ReturnType}>(left);
|
||||
public static List<{info.ReturnType}> operator *(List<{info.LeftType}> left, {info.RightType} right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * right._Value)" : "right._Value")}.Mul<{info.LeftType}, {info.ReturnType}>(left);
|
||||
public static IEnumerable<{info.ReturnType}> operator *(IEnumerable<{info.LeftType}> left, {info.RightType} right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * right._Value)" : "right._Value")}.Mul<{info.LeftType}, {info.ReturnType}>(left);
|
||||
}}";
|
||||
}
|
||||
|
||||
@@ -181,16 +174,16 @@ namespace {info.Namespace};
|
||||
|
||||
public readonly partial record struct {info.LeftType}
|
||||
{{
|
||||
public static {info.ReturnType}[] operator /({info.LeftType} left, {info.RightType}[] right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Divide<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static List<{info.ReturnType}> operator /({info.LeftType} left, List<{info.RightType}> right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Divide<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static IEnumerable<{info.ReturnType}> operator /({info.LeftType} left, IEnumerable<{info.RightType}> right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Divide<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static {info.ReturnType}[] operator /({info.LeftType} left, {info.RightType}[] right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Div<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static List<{info.ReturnType}> operator /({info.LeftType} left, List<{info.RightType}> right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Div<{info.RightType}, {info.ReturnType}>(right);
|
||||
public static IEnumerable<{info.ReturnType}> operator /({info.LeftType} left, IEnumerable<{info.RightType}> right) => {(info.HasCoeff ? $"({info.CoeffType}.{info.CoeffName} * left._Value)" : "left._Value")}.Div<{info.RightType}, {info.ReturnType}>(right);
|
||||
}}
|
||||
|
||||
public readonly partial record struct {info.RightType}
|
||||
{{
|
||||
public static {info.ReturnType}[] operator /({info.LeftType}[] left, {info.RightType} right) => {(info.HasCoeff ? $"left.Multiply<{info.LeftType}, {info.ReturnType}>({info.CoeffType}.{info.CoeffName} / right._Value)" : $"left.Divide<{info.LeftType}, {info.ReturnType}>(right._Value)")};
|
||||
public static List<{info.ReturnType}> operator /(List<{info.LeftType}> left, {info.RightType} right) => {(info.HasCoeff ? $"left.Multiply<{info.LeftType}, {info.ReturnType}>({info.CoeffType}.{info.CoeffName} / right._Value)" : $"left.Divide<{info.LeftType}, {info.ReturnType}>(right._Value)")};
|
||||
public static IEnumerable<{info.ReturnType}> operator /(IEnumerable<{info.LeftType}> left, {info.RightType} right) => {(info.HasCoeff ? $"left.Multiply<{info.LeftType}, {info.ReturnType}>({info.CoeffType}.{info.CoeffName} / right._Value)" : $"left.Divide<{info.LeftType}, {info.ReturnType}>(right._Value)")};
|
||||
public static {info.ReturnType}[] operator /({info.LeftType}[] left, {info.RightType} right) => {(info.HasCoeff ? $"left.Mul<{info.LeftType}, {info.ReturnType}>({info.CoeffType}.{info.CoeffName} / right._Value)" : $"left.Div<{info.LeftType}, {info.ReturnType}>(right._Value)")};
|
||||
public static List<{info.ReturnType}> operator /(List<{info.LeftType}> left, {info.RightType} right) => {(info.HasCoeff ? $"left.Mul<{info.LeftType}, {info.ReturnType}>({info.CoeffType}.{info.CoeffName} / right._Value)" : $"left.Div<{info.LeftType}, {info.ReturnType}>(right._Value)")};
|
||||
public static IEnumerable<{info.ReturnType}> operator /(IEnumerable<{info.LeftType}> left, {info.RightType} right) => {(info.HasCoeff ? $"left.Mul<{info.LeftType}, {info.ReturnType}>({info.CoeffType}.{info.CoeffName} / right._Value)" : $"left.Div<{info.LeftType}, {info.ReturnType}>(right._Value)")};
|
||||
}}";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -10,9 +9,6 @@ namespace G;
|
||||
[Generator]
|
||||
public class TestsGenerator : IIncrementalGenerator
|
||||
{
|
||||
private const string UnitAttributeFullName = "QWERTYkez.Mensura.UnitGeneratorAttribute";
|
||||
private const string ComplexAttributeFullName = "QWERTYkez.Mensura.ComplexUnitGeneratorAttribute";
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
var compilationProvider = context.CompilationProvider;
|
||||
@@ -24,116 +20,575 @@ public class TestsGenerator : IIncrementalGenerator
|
||||
|
||||
var mensuraAssembly = compilation.References
|
||||
.Select(r => compilation.GetAssemblyOrModuleSymbol(r) as IAssemblySymbol)
|
||||
.FirstOrDefault(a => a?.Name == "QWERTYkez.Mensura" || a?.Name?.EndsWith(".Mensura") == true);
|
||||
.FirstOrDefault(a => a?.Name == "QWERTYkez.Mensura");
|
||||
|
||||
if (mensuraAssembly == null)
|
||||
return;
|
||||
|
||||
var targetTypes = new List<INamedTypeSymbol>();
|
||||
CollectTypesWithAttribute(mensuraAssembly.GlobalNamespace, targetTypes, UnitAttributeFullName);
|
||||
CollectTypesWithAttribute(mensuraAssembly.GlobalNamespace, targetTypes, ComplexAttributeFullName);
|
||||
var unitTypes = CollectAllUnitTypes(mensuraAssembly.GlobalNamespace);
|
||||
if (unitTypes.Count == 0) return;
|
||||
|
||||
if (targetTypes.Count == 0)
|
||||
return;
|
||||
// 1. Сериализация
|
||||
GenerateSerializationTests(spc, unitTypes);
|
||||
|
||||
foreach (var type in targetTypes)
|
||||
{
|
||||
var unitProperties = GetStaticProperties(type);
|
||||
if (unitProperties.Length == 0) continue;
|
||||
var firstNonBase = unitProperties.FirstOrDefault(p => !p.Name.StartsWith("_"));
|
||||
if (firstNonBase.Name == null) continue;
|
||||
// 2. Операторы (с атрибутом)
|
||||
var operators = CollectOperatorsFromUnitTypes(unitTypes);
|
||||
if (operators.Length > 0)
|
||||
GenerateOperatorTests(spc, operators);
|
||||
|
||||
// Генерируем два файла
|
||||
GenerateSerializationTest(spc, type.Name, firstNonBase.Name, "SystemText", "System.Text.Json");
|
||||
GenerateSerializationTest(spc, type.Name, firstNonBase.Name, "Newtonsoft", "Newtonsoft.Json");
|
||||
}
|
||||
// 3. Коллекционные методы
|
||||
GenerateCollectionTests(spc, unitTypes);
|
||||
});
|
||||
}
|
||||
|
||||
private static void GenerateSerializationTest(SourceProductionContext spc, string typeName, string unitName, string framework, string namespaceName)
|
||||
// ========== 1. СЕРИАЛИЗАЦИЯ ==========
|
||||
private static void GenerateSerializationTests(SourceProductionContext spc, List<INamedTypeSymbol> types)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("// <auto-generated/>");
|
||||
sb.AppendLine("#pragma warning disable");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("using Xunit;");
|
||||
sb.AppendLine($"using {namespaceName};");
|
||||
sb.AppendLine("using System.Text.Json;");
|
||||
sb.AppendLine("using Newtonsoft.Json;");
|
||||
sb.AppendLine("using QWERTYkez.Mensura.Units;");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($"namespace QWERTYkez.Mensura.Tests");
|
||||
sb.AppendLine("namespace QWERTYkez.Mensura.Tests");
|
||||
sb.AppendLine("{");
|
||||
sb.AppendLine($" public class {typeName}Serialization_{framework}Tests");
|
||||
sb.AppendLine(" public class SerializationTests");
|
||||
sb.AppendLine(" {");
|
||||
sb.AppendLine($" private const double Tolerance = 1e-12;");
|
||||
sb.AppendLine($" private readonly {typeName} _testValue = {typeName}.{unitName};");
|
||||
sb.AppendLine(" private const double Tolerance = 1e-12;");
|
||||
sb.AppendLine();
|
||||
|
||||
// Тест
|
||||
sb.AppendLine(" [Fact]");
|
||||
sb.AppendLine($" public void {framework}_SerializeDeserialize_ReturnsEqualValue()");
|
||||
sb.AppendLine(" {");
|
||||
if (framework == "SystemText")
|
||||
foreach (var type in types)
|
||||
{
|
||||
sb.AppendLine(" var json = System.Text.Json.JsonSerializer.Serialize(_testValue);");
|
||||
var baseProp = GetBaseUnitProperty(type);
|
||||
if (baseProp == null) continue;
|
||||
var typeName = type.Name;
|
||||
var propName = baseProp.Name;
|
||||
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_SystemTextJson_SerializeDeserialize()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var original = {typeName}.{propName};");
|
||||
sb.AppendLine($" var json = System.Text.Json.JsonSerializer.Serialize(original);");
|
||||
sb.AppendLine($" var deserialized = System.Text.Json.JsonSerializer.Deserialize<{typeName}>(json);");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(" var json = Newtonsoft.Json.JsonConvert.SerializeObject(_testValue);");
|
||||
sb.AppendLine($" Assert.Equal((double)original, (double)deserialized, Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_NewtonsoftJson_SerializeDeserialize()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var original = {typeName}.{propName};");
|
||||
sb.AppendLine($" var json = Newtonsoft.Json.JsonConvert.SerializeObject(original);");
|
||||
sb.AppendLine($" var deserialized = Newtonsoft.Json.JsonConvert.DeserializeObject<{typeName}>(json);");
|
||||
sb.AppendLine($" Assert.Equal((double)original, (double)deserialized, Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
}
|
||||
sb.AppendLine(" Assert.Equal((double)_testValue, (double)deserialized, Tolerance);");
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine("}");
|
||||
|
||||
spc.AddSource($"Serialize.{framework}.{typeName}.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8));
|
||||
spc.AddSource("SerializationTests.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8));
|
||||
}
|
||||
|
||||
private static void CollectTypesWithAttribute(INamespaceSymbol ns, List<INamedTypeSymbol> results, string attributeFullName)
|
||||
// ========== 2. ОПЕРАТОРЫ (только с атрибутом) ==========
|
||||
private static ImmutableArray<OperatorInfo> CollectOperatorsFromUnitTypes(List<INamedTypeSymbol> unitTypes)
|
||||
{
|
||||
foreach (var type in ns.GetTypeMembers())
|
||||
var result = new List<OperatorInfo>();
|
||||
foreach (var containingType in unitTypes)
|
||||
{
|
||||
if (HasAttribute(type, attributeFullName))
|
||||
results.Add(type);
|
||||
}
|
||||
foreach (var childNs in ns.GetNamespaceMembers())
|
||||
{
|
||||
CollectTypesWithAttribute(childNs, results, attributeFullName);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasAttribute(INamedTypeSymbol type, string attributeFullName)
|
||||
{
|
||||
foreach (var attr in type.GetAttributes())
|
||||
{
|
||||
if (attr.AttributeClass?.ToString() == attributeFullName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ImmutableArray<UnitProperty> GetStaticProperties(INamedTypeSymbol type)
|
||||
{
|
||||
var props = new List<UnitProperty>();
|
||||
foreach (var member in type.GetMembers())
|
||||
{
|
||||
if (member is IPropertySymbol prop && prop.IsStatic && prop.DeclaredAccessibility == Accessibility.Public)
|
||||
foreach (var member in containingType.GetMembers())
|
||||
{
|
||||
var propName = prop.Name;
|
||||
if (propName == "EqualityContract" || propName.StartsWith("<"))
|
||||
if (member is not IMethodSymbol method || method.MethodKind != MethodKind.UserDefinedOperator)
|
||||
continue;
|
||||
props.Add(new UnitProperty(propName, prop.Type.ToString()));
|
||||
|
||||
bool hasAttr = method.GetAttributes().Any(attr =>
|
||||
attr.AttributeClass?.Name == "OperatorsGeneratorAttribute" ||
|
||||
attr.AttributeClass?.ToString() == "QWERTYkez.Mensura.OperatorsGeneratorAttribute");
|
||||
if (!hasAttr) continue;
|
||||
|
||||
string opSymbol = method.Name switch
|
||||
{
|
||||
"op_Multiply" => "*",
|
||||
"op_Division" => "/",
|
||||
_ => null
|
||||
};
|
||||
if (opSymbol == null) continue;
|
||||
|
||||
var pars = method.Parameters;
|
||||
if (pars.Length != 2) continue;
|
||||
|
||||
var leftType = pars[0].Type as INamedTypeSymbol;
|
||||
var rightType = pars[1].Type as INamedTypeSymbol;
|
||||
var returnType = method.ReturnType as INamedTypeSymbol;
|
||||
if (leftType == null || rightType == null || returnType == null) continue;
|
||||
|
||||
if (!unitTypes.Contains(leftType, SymbolEqualityComparer.Default) ||
|
||||
!unitTypes.Contains(rightType, SymbolEqualityComparer.Default) ||
|
||||
!unitTypes.Contains(returnType, SymbolEqualityComparer.Default))
|
||||
continue;
|
||||
|
||||
string? coeffField = null;
|
||||
foreach (var attr in method.GetAttributes())
|
||||
{
|
||||
if (attr.AttributeClass?.Name == "OperatorsGeneratorAttribute" ||
|
||||
attr.AttributeClass?.ToString() == "QWERTYkez.Mensura.OperatorsGeneratorAttribute")
|
||||
{
|
||||
foreach (var arg in attr.ConstructorArguments)
|
||||
{
|
||||
if (arg.Value is string s)
|
||||
{
|
||||
coeffField = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result.Add(new OperatorInfo(opSymbol, leftType, rightType, returnType, coeffField, containingType));
|
||||
}
|
||||
}
|
||||
return props.ToImmutableArray();
|
||||
return result.ToImmutableArray();
|
||||
}
|
||||
|
||||
private readonly struct UnitProperty
|
||||
private static void GenerateOperatorTests(SourceProductionContext spc, ImmutableArray<OperatorInfo> operators)
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Type { get; }
|
||||
public UnitProperty(string name, string type) => (Name, Type) = (name, type);
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("// <auto-generated/>");
|
||||
sb.AppendLine("#pragma warning disable");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("using Xunit;");
|
||||
sb.AppendLine("using QWERTYkez.Mensura.Units;");
|
||||
sb.AppendLine("using System.Reflection;");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("namespace QWERTYkez.Mensura.Tests");
|
||||
sb.AppendLine("{");
|
||||
sb.AppendLine(" public class OperatorsTests");
|
||||
sb.AppendLine(" {");
|
||||
sb.AppendLine(" private const double Tolerance = 1e-12;");
|
||||
sb.AppendLine();
|
||||
|
||||
foreach (var op in operators)
|
||||
{
|
||||
var leftBase = GetBaseUnitProperty(op.LeftType);
|
||||
var rightBase = GetBaseUnitProperty(op.RightType);
|
||||
if (leftBase == null || rightBase == null) continue;
|
||||
|
||||
string leftTypeName = op.LeftType.Name;
|
||||
string rightTypeName = op.RightType.Name;
|
||||
string returnTypeName = op.ReturnType.Name;
|
||||
string leftProp = leftBase.Name;
|
||||
string rightProp = rightBase.Name;
|
||||
|
||||
string testName = $"{op.OperatorSymbol}_{leftTypeName}_{rightTypeName}_Returns_{returnTypeName}"
|
||||
.Replace("<", "_").Replace(">", "_").Replace(",", "_").Replace(" ", "")
|
||||
.Replace("*", "Mul").Replace("/", "Div");
|
||||
|
||||
string expectedExpr;
|
||||
if (op.CoefficientField != null)
|
||||
{
|
||||
expectedExpr = $@"(double)left {op.OperatorSymbol} (double)right * " +
|
||||
$@"(double)typeof({op.ContainingType.Name}).GetField(""{op.CoefficientField}"", " +
|
||||
$@"BindingFlags.NonPublic | BindingFlags.Static).GetValue(null)";
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedExpr = $"(double)left {op.OperatorSymbol} (double)right";
|
||||
}
|
||||
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {testName}()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var left = {leftTypeName}.{leftProp};");
|
||||
sb.AppendLine($" var right = {rightTypeName}.{rightProp};");
|
||||
sb.AppendLine($" var result = left {op.OperatorSymbol} right;");
|
||||
sb.AppendLine($" var expected = {expectedExpr};");
|
||||
sb.AppendLine($" Assert.Equal(expected, (double)result, Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
if (operators.Length == 0)
|
||||
sb.AppendLine(" // No operators with [OperatorsGenerator] found");
|
||||
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine("}");
|
||||
spc.AddSource("OperatorsTests.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8));
|
||||
}
|
||||
|
||||
// ========== 3. КОЛЛЕКЦИОННЫЕ МЕТОДЫ ==========
|
||||
private static void GenerateCollectionTests(SourceProductionContext spc, List<INamedTypeSymbol> types)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("// <auto-generated/>");
|
||||
sb.AppendLine("#pragma warning disable");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("using Xunit;");
|
||||
sb.AppendLine("using QWERTYkez.Mensura.Units;");
|
||||
sb.AppendLine("using QWERTYkez.Mensura.Extensions;");
|
||||
sb.AppendLine("using System.Collections.Generic;");
|
||||
sb.AppendLine("using System.Linq;");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("namespace QWERTYkez.Mensura.Tests");
|
||||
sb.AppendLine("{");
|
||||
sb.AppendLine(" public class CollectionTests");
|
||||
sb.AppendLine(" {");
|
||||
sb.AppendLine(" private const double Tolerance = 1e-12;");
|
||||
sb.AppendLine();
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
var baseProp = GetBaseUnitProperty(type);
|
||||
if (baseProp == null) continue;
|
||||
|
||||
string typeName = type.Name;
|
||||
string propName = baseProp.Name;
|
||||
|
||||
// Создаём массив из двух тестовых значений
|
||||
sb.AppendLine($" private {typeName}[] GetTestArray() => new[] {{ {typeName}.{propName}, {typeName}.{propName} }};");
|
||||
sb.AppendLine();
|
||||
|
||||
// ========== Multiply ==========
|
||||
// scalar * array
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ScalarByArray_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Multiply(arr);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// array * scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ArrayByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Multiply(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar * List
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ScalarByList_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Multiply(list);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// List * scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ListByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Multiply(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar * IEnumerable
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_ScalarByEnumerable_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Multiply(enumerable);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// IEnumerable * scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Multiply_EnumerableByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Multiply(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar * (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
|
||||
// ========== Divide ==========
|
||||
// scalar / array
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ScalarByArray_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Divide(arr);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// array / scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ArrayByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Divide(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar / List
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ScalarByList_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Divide(list);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// List / scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ListByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Divide(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar / IEnumerable
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_ScalarByEnumerable_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Divide(enumerable);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// IEnumerable / scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Divide_EnumerableByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Divide(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar / (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
|
||||
// ========== Plus ==========
|
||||
// scalar + array
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ScalarByArray_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Plus(arr);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// array + scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ArrayByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Plus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar + List
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ScalarByList_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Plus(list);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// List + scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ListByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Plus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar + IEnumerable
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_ScalarByEnumerable_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Plus(enumerable);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// IEnumerable + scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Plus_EnumerableByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Plus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar + (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
|
||||
// ========== Minus ==========
|
||||
// scalar - array
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ScalarByArray_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = scalar.Minus(arr);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// array - scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ArrayByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var arr = GetTestArray();");
|
||||
sb.AppendLine($" var result = arr.Minus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Length);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar - List
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ScalarByList_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = scalar.Minus(list);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// List - scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ListByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var list = GetTestArray().ToList();");
|
||||
sb.AppendLine($" var result = list.Minus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[0], Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result[1], Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// scalar - IEnumerable
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_ScalarByEnumerable_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = scalar.Minus(enumerable);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
// IEnumerable - scalar
|
||||
sb.AppendLine($" [Fact]");
|
||||
sb.AppendLine($" public void {typeName}_Minus_EnumerableByScalar_Works()");
|
||||
sb.AppendLine($" {{");
|
||||
sb.AppendLine($" var scalar = {typeName}.{propName};");
|
||||
sb.AppendLine($" var enumerable = GetTestArray().AsEnumerable();");
|
||||
sb.AppendLine($" var result = enumerable.Minus(scalar);");
|
||||
sb.AppendLine($" Assert.Equal(2, result.Count());");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result.ElementAt(0), Tolerance);");
|
||||
sb.AppendLine($" Assert.Equal((double)scalar - (double)scalar, (double)result.ElementAt(1), Tolerance);");
|
||||
sb.AppendLine($" }}");
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine("}");
|
||||
spc.AddSource("CollectionTests.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8));
|
||||
}
|
||||
|
||||
// ========== ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ ==========
|
||||
private static List<INamedTypeSymbol> CollectAllUnitTypes(INamespaceSymbol root)
|
||||
{
|
||||
var result = new List<INamedTypeSymbol>();
|
||||
CollectTypesRecursive(root, result, "QWERTYkez.Mensura.Units");
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void CollectTypesRecursive(INamespaceSymbol ns, List<INamedTypeSymbol> result, string targetNamespacePrefix)
|
||||
{
|
||||
var nsFullName = ns.ToString();
|
||||
if (nsFullName.StartsWith(targetNamespacePrefix))
|
||||
{
|
||||
foreach (var type in ns.GetTypeMembers())
|
||||
result.Add(type);
|
||||
}
|
||||
foreach (var childNs in ns.GetNamespaceMembers())
|
||||
CollectTypesRecursive(childNs, result, targetNamespacePrefix);
|
||||
}
|
||||
|
||||
private static IPropertySymbol? GetBaseUnitProperty(ITypeSymbol type)
|
||||
{
|
||||
foreach (var member in type.GetMembers())
|
||||
{
|
||||
if (member is IPropertySymbol prop && prop.IsStatic && prop.Name.StartsWith("_") && SymbolEqualityComparer.Default.Equals(prop.Type, type))
|
||||
return prop;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private readonly struct OperatorInfo(string symbol, ITypeSymbol left, ITypeSymbol right, ITypeSymbol ret, string? coeff, ITypeSymbol containing)
|
||||
{
|
||||
public string OperatorSymbol { get; } = symbol;
|
||||
public ITypeSymbol LeftType { get; } = left;
|
||||
public ITypeSymbol RightType { get; } = right;
|
||||
public ITypeSymbol ReturnType { get; } = ret;
|
||||
public string? CoefficientField { get; } = coeff;
|
||||
public ITypeSymbol ContainingType { get; } = containing;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System.Text;
|
||||
|
||||
namespace G;
|
||||
namespace G;
|
||||
|
||||
[Generator]
|
||||
public class UnitGenerator : IIncrementalGenerator
|
||||
@@ -20,7 +14,7 @@ public class UnitGenerator : IIncrementalGenerator
|
||||
namespace QWERTYkez.Mensura
|
||||
{
|
||||
[System.AttributeUsage(System.AttributeTargets.Struct, AllowMultiple = false)]
|
||||
public sealed class UnitGeneratorAttribute : System.Attribute { }
|
||||
internal sealed class UnitGeneratorAttribute : System.Attribute { }
|
||||
}";
|
||||
ctx.AddSource(".UnitGeneratorAttribute.g.cs", SourceText.From(attributeSource, Encoding.UTF8));
|
||||
});
|
||||
@@ -36,11 +30,44 @@ namespace QWERTYkez.Mensura
|
||||
|
||||
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<QWERTYkez.Mensura.Units.{structInfo.TypeName}>());");
|
||||
}
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine("}");
|
||||
|
||||
spc.AddSource(".Units.MensuraBinder.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -98,7 +125,7 @@ using System.Runtime.Serialization;
|
||||
|
||||
namespace QWERTYkez.Mensura.Units;
|
||||
|
||||
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftUnitConverter<{typeName}>)), JsonConverter(typeof(UnitJsonConverter<{typeName}>))]
|
||||
[JsonConverter(typeof(UnitJsonConverter<{typeName}>))]
|
||||
public readonly partial record struct {typeName} : IMensuraUnit<{typeName}>, IEquatable<{typeName}>, IMensuraUnit
|
||||
{
|
||||
[JsonInclude, DataMember, JsonPropertyName(""v""), Obsolete] // для JSON / EF на случай сбоев, если пробелма с _Value
|
||||
@@ -286,7 +313,341 @@ public readonly partial record struct {typeName} : IMensuraUnit<{typeName}>, IEq
|
||||
|
||||
public static class {typeName}Extensions
|
||||
{
|
||||
public static double Protected(this {typeName}? unit) => unit is null ? 0d : unit.Value._Value;
|
||||
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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
[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<T> ===
|
||||
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<T> ===
|
||||
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<T> ===
|
||||
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<T> ===
|
||||
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<T> ===
|
||||
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<T> ===
|
||||
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<T> ===
|
||||
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<T> ===
|
||||
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);
|
||||
|
||||
8
QWERTYkez.Mensura.Generator/globals.cs
Normal file
8
QWERTYkez.Mensura.Generator/globals.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
global using Microsoft.CodeAnalysis;
|
||||
global using Microsoft.CodeAnalysis.CSharp;
|
||||
global using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
global using Microsoft.CodeAnalysis.Text;
|
||||
global using System.Collections.Immutable;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Text;
|
||||
Reference in New Issue
Block a user