From 53260fe06aa06109242490ae7f1cfd455b33a69a Mon Sep 17 00:00:00 2001 From: hadashiA Date: Mon, 14 Aug 2023 14:52:57 +0900 Subject: [PATCH 01/12] Support INumber and add operator options separately --- src/UnitGenerator/SourceGenerator.cs | 473 +++++++++++++++++++---- src/UnitGenerator/UnitGenerateOptions.cs | 14 +- 2 files changed, 402 insertions(+), 85 deletions(-) diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index 88a1b06..33a1226 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -85,7 +85,7 @@ public void Execute(GeneratorExecutionContext context) ToStringFormat = prop.ToStringFormat }; - var text = GenerateType(typeSymbol, prop); + var text = GenerateType(typeSymbol, prop); if (template.Namespace == null) { context.AddSource($"{template.Name}.Generated.cs", text); @@ -110,6 +110,7 @@ private void SetDefaultAttribute(GeneratorPostInitializationContext context) // #pragma warning disable CS8669 #pragma warning disable CS8625 +#nullable enable using System; namespace UnitGenerator @@ -128,7 +129,7 @@ public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOpti this.Format = toStringFormat; } } - + [Flags] internal enum UnitGenerateOptions { @@ -148,7 +149,20 @@ internal enum UnitGenerateOptions JsonConverterDictionaryKeySupport = 1 << 12, Normalize = 1 << 13, } + + [Flags] + internal enum UnitGenerateArithmeticOperator + { + Number = 0, + Addition = 1, + Subtraction = 1 << 1, + Multiply = 1 << 2, + Division = 1 << 3, + Increment = 1 << 4, + Decrement = 1 << 5, + } } + """; context.AddSource("UnitOfAttribute.cs", attrCode); } @@ -158,15 +172,25 @@ private string GenerateType(INamedTypeSymbol symbol, UnitOfAttributeProperty pro var unitTypeName = symbol.Name; var innerTypeName = prop.TypeName; var ns = symbol.ContainingNamespace.IsGlobalNamespace ? null : symbol.ContainingNamespace.ToDisplayString(); - + var sb = new StringBuilder(""" // // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // #pragma warning disable CS8669 +#nullable enable using System; """); + if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) + { + sb.AppendLine(""" +#if NET7_0_OR_GREATER +using System.Numerics; +using System.Globalization; +#endif +"""); + } if (prop.HasFlag(UnitGenerateOptions.MessagePackFormatter)) { sb.AppendLine(""" @@ -203,13 +227,96 @@ namespace {{ns}} if (prop.HasFlag(UnitGenerateOptions.MessagePackFormatter)) { sb.AppendLine($$""" - [MessagePackFormatter(typeof({{unitTypeName}}MessagePackFormatter))] + [MessagePackFormatter(typeof({{unitTypeName}}MessagePackFormatter))] """); } - var comparableDeclare = prop.HasFlag(UnitGenerateOptions.Comparable) ? $", IComparable<{unitTypeName}>" : ""; + sb.AppendLine($$""" [System.ComponentModel.TypeConverter(typeof({{unitTypeName}}TypeConverter))] - readonly partial struct {{unitTypeName}} : IEquatable<{{unitTypeName}}>{{comparableDeclare}} + readonly partial struct {{unitTypeName}} +"""); + if (prop.IsNumber()) + { + sb.AppendLine($$""" +#if NET7_0_OR_GREATER + : INumber<{{unitTypeName}}> +#endif +"""); + } + else + { + sb.AppendLine($$""" + : IEquatable<{{{unitTypeName}}>"); +#if NET7_0_OR_GREATER + , IEqualityOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> +#endif +"""); + if (prop.HasFlag(UnitGenerateOptions.Comparable)) + { + sb.AppendLine($$""" + , IComparable<{{unitTypeName}}> +"""); + } + if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) + { + sb.AppendLine("#if NET7_0_OR_GREATER"); + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition)) + { + sb.AppendLine($$""" + , IAdditionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> + , IUnaryPlusOperators<{{unitTypeName}}, {{unitTypeName}}> +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Subtraction)) + { + sb.AppendLine($$""" + , ISubtractionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> + , IUnaryNegationOperators<{{unitTypeName}}, {{unitTypeName}}> +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition | + UnitGenerateArithmeticOperator.Subtraction)) + { + sb.AppendLine($$""" + , IAdditiveIdentity<{{unitTypeName}}, {{unitTypeName}}> +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply)) + { + sb.AppendLine($$""" + , IMultiplyOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Division)) + { + sb.AppendLine($$""" + , IDivisionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply | + UnitGenerateArithmeticOperator.Division)) + { + sb.AppendLine($$""" + , IMultiplicativeIdentity<{{unitTypeName}}, {{unitTypeName}}> +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Increment)) + { + sb.AppendLine($$""" + , IIncrementOperators<{{unitTypeName}}> +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Decrement)) + { + sb.AppendLine($$""" + , IDecrementOperators<{{unitTypeName}}> +"""); + } + sb.AppendLine("#endif"); + } + } + + sb.AppendLine($$""" { readonly {{innerTypeName}} value; @@ -245,12 +352,12 @@ namespace {{ns}} } if (prop.HasFlag(UnitGenerateOptions.Validate)) { - sb.AppendLine($$""" + sb.AppendLine(""" private partial void Validate(); - + """); } - + var convertModifier = prop.HasFlag(UnitGenerateOptions.ImplicitOperator) ? "implicit" : "explicit"; sb.AppendLine($$""" public static {{convertModifier}} operator {{innerTypeName}}({{unitTypeName}} value) @@ -283,6 +390,16 @@ public override bool Equals(object obj) return value.Equals(obj); } + + public static bool operator ==(in {{unitTypeName}} x, in {{unitTypeName}} y) + { + return x.value.Equals(y.value); + } + + public static bool operator !=(in {{unitTypeName}} x, in {{unitTypeName}} y) + { + return !x.value.Equals(y.value); + } public override int GetHashCode() { @@ -302,7 +419,7 @@ public override string ToString() } else { - sb.AppendLine($$""" + sb.AppendLine(""" public override string ToString() { return value.ToString(); @@ -310,18 +427,7 @@ public override string ToString() """); } - sb.AppendLine($$""" - public static bool operator ==(in {{unitTypeName}} x, in {{unitTypeName}} y) - { - return x.value.Equals(y.value); - } - public static bool operator !=(in {{unitTypeName}} x, in {{unitTypeName}} y) - { - return !x.value.Equals(y.value); - } - -"""); if (prop.IsGuid()) { sb.AppendLine($$""" @@ -357,11 +463,12 @@ public override string ToString() """); } - + if (prop.HasFlag(UnitGenerateOptions.ParseMethod)) { sb.AppendLine(""" // UnitGenerateOptions.ParseMethod + """); if (prop.IsString()) { @@ -384,7 +491,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) return false; } } - + """); } else @@ -408,7 +515,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) return false; } } - + """); } } @@ -426,7 +533,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { return new {{unitTypeName}}(Math.Max(x.value, y.value)); } - + """); } @@ -455,9 +562,23 @@ public static bool TryParse(string s, out {{unitTypeName}} result) if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) { - sb.AppendLine($$""" + sb.AppendLine(""" // UnitGenerateOptions.ArithmeticOperator + +"""); + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition | + UnitGenerateArithmeticOperator.Subtraction)) + { + sb.AppendLine($$""" +#if NET7_0_OR_GREATER + public static {{unitTypeName}} AdditiveIdentity => {{innerTypeName}}.AdditiveIdentity; + +#endif +"""); + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition)) + { + sb.AppendLine($$""" public static {{unitTypeName}} operator +(in {{unitTypeName}} x, in {{unitTypeName}} y) { checked @@ -466,38 +587,64 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } - public static {{unitTypeName}} operator -(in {{unitTypeName}} x, in {{unitTypeName}} y) +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Subtraction)) + { + sb.AppendLine($$""" + public static {{unitTypeName}} operator -(in {{unitTypeName}} x, in {{innerTypeName}} y) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value - y.value)); + return new {{unitTypeName}}(({{innerTypeName}})(x.value - y)); } } - public static {{unitTypeName}} operator *(in {{unitTypeName}} x, in {{unitTypeName}} y) +"""); + } + } // End Addition, Subtraction + + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply | + UnitGenerateArithmeticOperator.Division)) + { + sb.AppendLine($$""" +#if NET7_0_OR_GREATER + public static {{unitTypeName}} MultiplicativeIdentity => {{innerTypeName}}.MultiplicativeIdentity; + +#endif +"""); + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply)) + { + sb.AppendLine($$""" + public static {{unitTypeName}} operator *(in {{unitTypeName}} x, in {{innerTypeName}} y) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value * y.value)); + return new {{unitTypeName}}(({{innerTypeName}})(x.value * y)); } } - public static {{unitTypeName}} operator /(in {{unitTypeName}} x, in {{unitTypeName}} y) +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Division)) + { + sb.AppendLine($$""" + + public static {{unitTypeName}} operator /(in {{unitTypeName}} x, in {{innerTypeName}} y) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value / y.value)); + return new {{unitTypeName}}(({{innerTypeName}})(x.value / y)); } } - -"""); - } - if (prop.HasFlag(UnitGenerateOptions.ValueArithmeticOperator)) - { - sb.AppendLine($$""" - // UnitGenerateOptions.ValueArithmeticOperator +"""); + } + } // End Multiply, Division + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Increment)) + { + sb.AppendLine($$""" public static {{unitTypeName}} operator ++(in {{unitTypeName}} x) { checked @@ -506,6 +653,11 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } +"""); + } + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Decrement)) + { + sb.AppendLine($$""" public static {{unitTypeName}} operator --(in {{unitTypeName}} x) { checked @@ -514,78 +666,224 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } - public static {{unitTypeName}} operator +(in {{unitTypeName}} x, in {{innerTypeName}} y) +"""); + } + } // End ArithmeticOperator + + if (prop.IsNumber() || prop.HasFlag(UnitGenerateOptions.Comparable)) + { + sb.AppendLine($$""" + // UnitGenerateOptions.Comparable + + public int CompareTo({{unitTypeName}} other) { - checked + return value.CompareTo(other.value); + } + +"""); + } + if (prop.IsNumber() || + (prop.HasFlag(UnitGenerateOptions.Comparable) && !prop.HasFlag(UnitGenerateOptions.WithoutComparisonOperator))) { - return new {{unitTypeName}}(({{innerTypeName}})(x.value + y)); + sb.AppendLine($$""" + public static bool operator >(in {{unitTypeName}} x, in {{unitTypeName}} y) + { + return x.value > y.value; + } + + public static bool operator <(in {{unitTypeName}} x, in {{unitTypeName}} y) + { + return x.value < y.value; + } + + public static bool operator >=(in {{unitTypeName}} x, in {{unitTypeName}} y) + { + return x.value >= y.value; + } + + public static bool operator <=(in {{unitTypeName}} x, in {{unitTypeName}} y) + { + return x.value <= y.value; + } + +"""); } + + if (prop.IsNumber()) + { + sb.AppendLine($$""" + public static {{unitTypeName}} operator %({{unitTypeName}} x, {{unitTypeName}} y) => x.value % y.value; + + // IFormattable + + public string ToString(string? format, IFormatProvider? formatProvider) => value.ToString(format, formatProvider); + +#if NET6_0_OR_GREATER + // ISpanFormattable + + public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) + { + return value.TryFormat(destination, out charsWritten, format, provider); } + +#endif +#if NET7_0_OR_GREATER + // IParsable + + public static {{unitTypeName}} Parse(string s, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, provider)); - public static {{unitTypeName}} operator -(in {{unitTypeName}} x, in {{innerTypeName}} y) + public static bool TryParse(string? s, IFormatProvider? provider, out {{unitTypeName}} result) { - checked + if ({{innerTypeName}}.TryParse(s, provider, out var parsedValue)) { - return new {{unitTypeName}}(({{innerTypeName}})(x.value - y)); + result = new {{unitTypeName}}(parsedValue); + return true; } + result = default; + return false; } - - public static {{unitTypeName}} operator *(in {{unitTypeName}} x, in {{innerTypeName}} y) + + // ISpanParsable + + public static {{unitTypeName}} Parse(ReadOnlySpan s, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, provider)); + + public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out {{unitTypeName}} result) { - checked + if ({{innerTypeName}}.TryParse(s, provider, out var parsedValue)) { - return new {{unitTypeName}}(({{innerTypeName}})(x.value * y)); + result = new {{unitTypeName}}(parsedValue); + return true; } + result = default; + return false; } - public static {{unitTypeName}} operator /(in {{unitTypeName}} x, in {{innerTypeName}} y) + // INumber + + public static {{unitTypeName}} One => {{innerTypeName}}.One; + public static int Radix => {{innerTypeName}}.Radix; + public static {{unitTypeName}} Zero => {{innerTypeName}}.Zero; + + public static {{unitTypeName}} Abs({{unitTypeName}} value) => {{innerTypeName}}.Abs(value.value); + + public static bool IsCanonical({{unitTypeName}} value) => {{innerTypeName}}.IsCanonical(value.value); + + public static bool IsComplexNumber({{unitTypeName}} value) => {{innerTypeName}}.IsComplexNumber(value.value); + + public static bool IsEvenInteger({{unitTypeName}} value) => {{innerTypeName}}.IsEventInteger(value.value); + + public static bool IsFinite({{unitTypeName}} value) => {{innerTypeName}}.IsFinite(value.value); + + public static bool IsImaginaryNumber({{unitTypeName}} value) => {{innerTypeName}}.IsImaginaryNumber(value.value); + + public static bool IsInfinity({{unitTypeName}} value) => {{innerTypeName}}.IsInfinity(value.value); + + public static bool IsInteger({{unitTypeName}} value) => {{innerTypeName}}.IsInteger(value.value); + + public static bool IsNaN({{unitTypeName}} value) => {{innerTypeName}}.IsNaN(value.value); + + public static bool IsNegative({{unitTypeName}} value) => {{innerTypeName}}.IsNegative(value.value); + + public static bool IsNegativeInfinity({{unitTypeName}} value) => {{innerTypeName}}.IsNegativeInfinity(value.value); + + public static bool IsNormal({{unitTypeName}} value) => {{innerTypeName}}.IsNormal(value.value); + + public static bool IsOddInteger({{unitTypeName}} value) => {{innerTypeName}}.IsOddInteger(value.value); + + public static bool IsPositive({{unitTypeName}} value) => {{innerTypeName}}.IsPositive(value.value); + + public static bool IsPositiveInfinity({{unitTypeName}} value) => {{innerTypeName}}.IsPositiveInfinity(value.value); + + public static bool IsRealNumber({{unitTypeName}} value) => {{innerTypeName}}.IsRealNumber(value.value); + + public static bool IsSubnormal({{unitTypeName}} value) => {{innerTypeName}}.IsSubnormal(value.value); + + public static bool IsZero({{unitTypeName}} value) => {{innerTypeName}}.IsZero(value.value); + + public static {{unitTypeName}} MaxMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => {{innerTypeName}}.MaxMagnitude(x.value, y.value); + + public static {{unitTypeName}} MaxMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => {{innerTypeName}}.MaxMagnitudeNumber(x.value, y.value); + + public static {{unitTypeName}} MinMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => {{innerTypeName}}.MinMagnitude(x.value, y.value); + + public static {{unitTypeName}} MinMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => {{innerTypeName}}.MinMagnitudeNumber(x.value, y.value); + + public static bool TryConvertFromChecked(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - checked + if ({{innerTypeName}}.TryConvertFromChecked(value, out var innerResult)) { - return new {{unitTypeName}}(({{innerTypeName}})(x.value / y)); + result = new {{unitTypeName}}(innerResult); + return true; } + result = default; + return false; } -"""); + public static bool TryConvertFromSaturating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase + { + if ({{innerTypeName}}.TryConvertFromSaturating(value, out var innerResult) + { + result = new {{unitTypeName}}(innerResult); + return true; } + result = default; + return false; + } - if (prop.HasFlag(UnitGenerateOptions.Comparable)) + public static bool TryConvertFromTruncating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase + { + if ({{innerTypeName}}.TryConvertFromTruncating(value, out var innerResult)) { - sb.AppendLine($$""" - // UnitGenerateOptions.Comparable + result = new {{unitTypeName}}(innerResult); + return true; + } + result = default; + return false; + } - public int CompareTo({{unitTypeName}} other) + public static bool TryConvertToChecked({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return value.CompareTo(other.value); + return ({{innerTypeName}}.TryConvertToChecked(value.value, out result)); } -"""); - if (!prop.HasFlag(UnitGenerateOptions.WithoutComparisonOperator)) - { - sb.AppendLine($$""" - public static bool operator >(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool TryConvertToSaturating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return x.value > y.value; + return {{innerTypeName}}.TryConvertToSaturating(value.value, out result); } - public static bool operator <(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool TryConvertToTruncating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return x.value < y.value; + return {{innerTypeName}}.TryConvertToTruncating(value.value, out result); } + + public static {{unitTypeName}} Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); + public static {{unitTypeName}} Parse(string s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); - public static bool operator >=(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out {{unitTypeName}} result) { - return x.value >= y.value; + if ({{innerTypeName}}.TryParse(s, style, provider, out var value)) + { + result = new {{unitTypeName}}(value); + return true; + } + result = default; + return false; } - public static bool operator <=(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out {{unitTypeName}} result) { - return x.value <= y.value; - } - + if ({{innerTypeName}}.TryParse(s, style, provider, out var value)) + { + result = new {{unitTypeName}}(value); + return true; + } + result = default; + return false; + } +#endif + """); - } // End ComparisonOperator - } // End Comparable + } // End Number if (prop.HasFlag(UnitGenerateOptions.JsonConverter)) { @@ -665,7 +963,7 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, {{unitTypeName}} { return new {{unitTypeName}}({{innerTypeName}}.Parse(reader.GetString())); } - + """); } else if (prop.IsString()) @@ -680,7 +978,7 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, {{unitTypeName}} { return new {{unitTypeName}}(reader.GetString()); } - + """); } else @@ -696,10 +994,10 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, {{unitTypeName}} return new {{unitTypeName}}({{innerTypeName}}.Parse(reader.GetString())); } -"""); +"""); } } // End JsonConverterDictionaryKeySupport - + sb.AppendLine($$""" } @@ -777,8 +1075,8 @@ public class {{unitTypeName}}ValueConverter : Microsoft.EntityFrameworkCore.Stor """); } // End EntityFrameworkValueConverter - - + + sb.AppendLine($$""" // Default private class {{unitTypeName}}TypeConverter : System.ComponentModel.TypeConverter @@ -856,17 +1154,24 @@ struct UnitOfAttributeProperty { public ITypeSymbol Type { get; set; } public UnitGenerateOptions Options { get; set; } + public UnitGenerateArithmeticOperator ArithmeticOperator { get; set; } public string? ToStringFormat { get; set; } public string TypeName => Type.ToString(); - + public bool IsString() => TypeName is "string"; public bool IsBool() => TypeName is "bool"; public bool IsUlid() => TypeName is "Ulid" or "System.Ulid"; public bool IsGuid() => TypeName is "Guid" or "System.Guid"; - - public bool HasFlag(UnitGenerateOptions options) + + public bool IsNumber() => HasFlag(UnitGenerateOptions.ArithmeticOperator) && + ArithmeticOperator == UnitGenerateArithmeticOperator.Number; + + public bool HasFlag(UnitGenerateOptions options) => Options.HasFlag(options); + + public bool HasArithmeticOperator(UnitGenerateArithmeticOperator op) { - return Options.HasFlag(options); + return HasFlag(UnitGenerateOptions.ArithmeticOperator) && + ArithmeticOperator.HasFlag(op); } public DbType GetDbType() diff --git a/src/UnitGenerator/UnitGenerateOptions.cs b/src/UnitGenerator/UnitGenerateOptions.cs index 5dd7da8..7573fe3 100644 --- a/src/UnitGenerator/UnitGenerateOptions.cs +++ b/src/UnitGenerator/UnitGenerateOptions.cs @@ -2,7 +2,7 @@ namespace UnitGenerator { - // same as Generated Options(check UnitOfAttributeTemplate.tt). + // same as Generated Options(check SourceGenerator.cs). [Flags] internal enum UnitGenerateOptions { @@ -22,4 +22,16 @@ internal enum UnitGenerateOptions JsonConverterDictionaryKeySupport = 1 << 12, Normalize = 1 << 13, } + + [Flags] + internal enum UnitGenerateArithmeticOperator + { + Number = 0, + Addition = 1, + Subtraction = 1 << 1, + Multiply = 1 << 2, + Division = 1 << 3, + Increment = 1 << 4, + Decrement = 1 << 5, + } } From a90b5b6e39f08c416e5570078554e71ea328a54a Mon Sep 17 00:00:00 2001 From: hadashiA Date: Tue, 15 Aug 2023 11:47:24 +0900 Subject: [PATCH 02/12] Fix missing INumberBase members --- sandbox/ConsoleApp/AllPrimitives.cs | 22 +- sandbox/ConsoleApp/ConsoleApp.csproj | 2 +- sandbox/ConsoleApp/Others.cs | 151 +++++++++++++ sandbox/ConsoleApp/Program.cs | 5 +- sandbox/FileGenerate/FileGenerate.csproj | 2 +- .../FileGenerate.A.Generated.cs | 25 ++- .../FileGenerate.B.Generated.cs | 25 ++- .../UnitOfAttribute.cs | 48 +++- .../EntityFrameworkApp.csproj | 2 +- src/UnitGenerator/SourceGenerator.cs | 205 +++++++++--------- 10 files changed, 351 insertions(+), 136 deletions(-) diff --git a/sandbox/ConsoleApp/AllPrimitives.cs b/sandbox/ConsoleApp/AllPrimitives.cs index 7433c77..9c69366 100644 --- a/sandbox/ConsoleApp/AllPrimitives.cs +++ b/sandbox/ConsoleApp/AllPrimitives.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Numerics; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; @@ -23,7 +25,7 @@ private partial void Validate() } } - [UnitOf(typeof(int), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(int), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct T { private partial void Validate() @@ -32,7 +34,7 @@ private partial void Validate() } } - [UnitOf(typeof(uint), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(uint), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct B { private partial void Validate() @@ -41,7 +43,7 @@ private partial void Validate() } } - [UnitOf(typeof(short), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(short), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct C { private partial void Validate() @@ -50,7 +52,7 @@ private partial void Validate() } } - [UnitOf(typeof(ushort), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(ushort), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct D { private partial void Validate() @@ -59,7 +61,7 @@ private partial void Validate() } } - [UnitOf(typeof(byte), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(byte), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct E { private partial void Validate() @@ -68,7 +70,7 @@ private partial void Validate() } } - [UnitOf(typeof(sbyte), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(sbyte), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct F { private partial void Validate() @@ -77,7 +79,7 @@ private partial void Validate() } } - [UnitOf(typeof(float), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(float), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct G { private partial void Validate() @@ -86,7 +88,7 @@ private partial void Validate() } } - [UnitOf(typeof(double), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(double), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct H { private partial void Validate() @@ -95,7 +97,7 @@ private partial void Validate() } } - [UnitOf(typeof(decimal), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(decimal), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct I { private partial void Validate() @@ -104,7 +106,7 @@ private partial void Validate() } } - [UnitOf(typeof(float), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(float), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct J { private partial void Validate() diff --git a/sandbox/ConsoleApp/ConsoleApp.csproj b/sandbox/ConsoleApp/ConsoleApp.csproj index 9035ba9..cc776ea 100644 --- a/sandbox/ConsoleApp/ConsoleApp.csproj +++ b/sandbox/ConsoleApp/ConsoleApp.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 enable false diff --git a/sandbox/ConsoleApp/Others.cs b/sandbox/ConsoleApp/Others.cs index 92eb317..c1b68b7 100644 --- a/sandbox/ConsoleApp/Others.cs +++ b/sandbox/ConsoleApp/Others.cs @@ -1,13 +1,21 @@ using System; +using System.Globalization; +using System.Numerics; using UnitGenerator; namespace ConsoleApp { + internal static class NumberProxy where T : INumber + { + private static T One() => T.One; + } + [UnitOf(typeof(Guid), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.Validate | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter)] public readonly partial struct GD { private partial void Validate() { + UnitGenerator.NumberProxy.One(); _ = AsPrimitive(); } } @@ -35,4 +43,147 @@ private partial void Validate() _ = AsPrimitive(); } } + + public class N2 : IEquatable + { + public int X { get; } + + public bool Equals(N2? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return X == other.X; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((N2)obj); + } + + public override int GetHashCode() => X; + } + + public class N : INumber + { + public int CompareTo(object? obj) => throw new NotImplementedException(); + + public int CompareTo(N? other) => throw new NotImplementedException(); + + public bool Equals(N? other) => throw new NotImplementedException(); + + public string ToString(string? format, IFormatProvider? formatProvider) => throw new NotImplementedException(); + + public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) => throw new NotImplementedException(); + + public static N Parse(string s, IFormatProvider? provider) => throw new NotImplementedException(); + + public static bool TryParse(string? s, IFormatProvider? provider, out N result) => throw new NotImplementedException(); + + public static N Parse(ReadOnlySpan s, IFormatProvider? provider) => throw new NotImplementedException(); + + public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out N result) => throw new NotImplementedException(); + + public static N operator +(N left, N right) => throw new NotImplementedException(); + + public static N AdditiveIdentity { get; } + public static bool operator ==(N? left, N? right) => throw new NotImplementedException(); + + public static bool operator !=(N? left, N? right) => throw new NotImplementedException(); + + public static bool operator >(N left, N right) => throw new NotImplementedException(); + + public static bool operator >=(N left, N right) => throw new NotImplementedException(); + + public static bool operator <(N left, N right) => throw new NotImplementedException(); + + public static bool operator <=(N left, N right) => throw new NotImplementedException(); + + public static N operator --(N value) => throw new NotImplementedException(); + + public static N operator /(N left, N right) => throw new NotImplementedException(); + + public static N operator ++(N value) => throw new NotImplementedException(); + + public static N operator %(N left, N right) => throw new NotImplementedException(); + + public static N MultiplicativeIdentity { get; } + public static N operator *(N left, N right) => throw new NotImplementedException(); + + public static N operator -(N left, N right) => throw new NotImplementedException(); + + public static N operator -(N value) => throw new NotImplementedException(); + + public static N operator +(N value) => throw new NotImplementedException(); + + public static N Abs(N value) => throw new NotImplementedException(); + + public static bool IsCanonical(N value) => throw new NotImplementedException(); + + public static bool IsComplexNumber(N value) => throw new NotImplementedException(); + + public static bool IsEvenInteger(N value) => throw new NotImplementedException(); + + public static bool IsFinite(N value) => throw new NotImplementedException(); + + public static bool IsImaginaryNumber(N value) => throw new NotImplementedException(); + + public static bool IsInfinity(N value) => throw new NotImplementedException(); + + public static bool IsInteger(N value) => throw new NotImplementedException(); + + public static bool IsNaN(N value) => throw new NotImplementedException(); + + public static bool IsNegative(N value) => throw new NotImplementedException(); + + public static bool IsNegativeInfinity(N value) => throw new NotImplementedException(); + + public static bool IsNormal(N value) => throw new NotImplementedException(); + + public static bool IsOddInteger(N value) => throw new NotImplementedException(); + + public static bool IsPositive(N value) => throw new NotImplementedException(); + + public static bool IsPositiveInfinity(N value) => throw new NotImplementedException(); + + public static bool IsRealNumber(N value) => throw new NotImplementedException(); + + public static bool IsSubnormal(N value) => throw new NotImplementedException(); + + public static bool IsZero(N value) => throw new NotImplementedException(); + + public static N MaxMagnitude(N x, N y) => throw new NotImplementedException(); + + public static N MaxMagnitudeNumber(N x, N y) => throw new NotImplementedException(); + + public static N MinMagnitude(N x, N y) => throw new NotImplementedException(); + + public static N MinMagnitudeNumber(N x, N y) => throw new NotImplementedException(); + + public static N Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => throw new NotImplementedException(); + + public static N Parse(string s, NumberStyles style, IFormatProvider? provider) => throw new NotImplementedException(); + + public static bool TryConvertFromChecked(TOther value, out N result) where TOther : INumberBase => throw new NotImplementedException(); + + public static bool TryConvertFromSaturating(TOther value, out N result) where TOther : INumberBase => throw new NotImplementedException(); + + public static bool TryConvertFromTruncating(TOther value, out N result) where TOther : INumberBase => throw new NotImplementedException(); + + public static bool TryConvertToChecked(N value, out TOther result) where TOther : INumberBase => throw new NotImplementedException(); + + public static bool TryConvertToSaturating(N value, out TOther result) where TOther : INumberBase => throw new NotImplementedException(); + + public static bool TryConvertToTruncating(N value, out TOther result) where TOther : INumberBase => throw new NotImplementedException(); + + public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out N result) => throw new NotImplementedException(); + + public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out N result) => throw new NotImplementedException(); + + public static N One { get; } + public static int Radix { get; } + public static N Zero { get; } + } } diff --git a/sandbox/ConsoleApp/Program.cs b/sandbox/ConsoleApp/Program.cs index 84f0262..5b291fe 100644 --- a/sandbox/ConsoleApp/Program.cs +++ b/sandbox/ConsoleApp/Program.cs @@ -35,8 +35,7 @@ public readonly partial struct BarId { } namespace Sample { - - [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct Hp { // public static Hp operator +(in Hp x, in Hp y) => new Hp(checked((int)(x.value + y.value))); @@ -83,7 +82,7 @@ public void Foo() _ = AsPrimitive(); } } - + [UnitOf(typeof(string), UnitGenerateOptions.ParseMethod)] public readonly partial struct StringId { } } diff --git a/sandbox/FileGenerate/FileGenerate.csproj b/sandbox/FileGenerate/FileGenerate.csproj index 96575cf..3373f19 100644 --- a/sandbox/FileGenerate/FileGenerate.csproj +++ b/sandbox/FileGenerate/FileGenerate.csproj @@ -1,7 +1,7 @@  - net6.0 + net7.0 true $(ProjectDir)..\Generated diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs index 6608197..4c88b2b 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs @@ -2,11 +2,16 @@ // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // #pragma warning disable CS8669 +#nullable enable using System; namespace FileGenerate { [System.ComponentModel.TypeConverter(typeof(ATypeConverter))] - readonly partial struct A : IEquatable + readonly partial struct A + : IEquatable<{A> +#if NET7_0_OR_GREATER + , IEqualityOperators +#endif { readonly int value; @@ -47,25 +52,25 @@ public override bool Equals(object obj) return value.Equals(obj); } - - public override int GetHashCode() + + public static bool operator ==(A x, A y) { - return value.GetHashCode(); + return x.value.Equals(y.value); } - public override string ToString() + public static bool operator !=(A x, A y) { - return value.ToString(); + return !x.value.Equals(y.value); } - public static bool operator ==(in A x, in A y) + public override int GetHashCode() { - return x.value.Equals(y.value); + return value.GetHashCode(); } - public static bool operator !=(in A x, in A y) + public override string ToString() { - return !x.value.Equals(y.value); + return value.ToString(); } // Default diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs index 6173d2b..07ba15a 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs @@ -2,11 +2,16 @@ // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // #pragma warning disable CS8669 +#nullable enable using System; namespace FileGenerate { [System.ComponentModel.TypeConverter(typeof(BTypeConverter))] - readonly partial struct B : IEquatable + readonly partial struct B + : IEquatable<{B> +#if NET7_0_OR_GREATER + , IEqualityOperators +#endif { readonly string value; @@ -47,25 +52,25 @@ public override bool Equals(object obj) return value.Equals(obj); } - - public override int GetHashCode() + + public static bool operator ==(B x, B y) { - return value.GetHashCode(); + return x.value.Equals(y.value); } - public override string ToString() + public static bool operator !=(B x, B y) { - return value.ToString(); + return !x.value.Equals(y.value); } - public static bool operator ==(in B x, in B y) + public override int GetHashCode() { - return x.value.Equals(y.value); + return value.GetHashCode(); } - public static bool operator !=(in B x, in B y) + public override string ToString() { - return !x.value.Equals(y.value); + return value.ToString(); } // Default diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs index 6eb676e..bfe259d 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs @@ -3,6 +3,7 @@ // #pragma warning disable CS8669 #pragma warning disable CS8625 +#nullable enable using System; namespace UnitGenerator @@ -21,7 +22,7 @@ public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOpti this.Format = toStringFormat; } } - + [Flags] internal enum UnitGenerateOptions { @@ -41,4 +42,47 @@ internal enum UnitGenerateOptions JsonConverterDictionaryKeySupport = 1 << 12, Normalize = 1 << 13, } -} \ No newline at end of file + + [Flags] + internal enum UnitGenerateArithmeticOperator + { + Number = 0, + Addition = 1, + Subtraction = 1 << 1, + Multiply = 1 << 2, + Division = 1 << 3, + Increment = 1 << 4, + Decrement = 1 << 5, + } + +#if NET7_0_OR_GREATER + internal static class NumberProxy where T : INumber + { + public static T One => T.One; + public static int Radix => T.Radix; + public static T Zero => T.Zero; + public static T Abs(T value) => T.Abs(value); + public static bool IsCanonical(T value) => T.IsCanonical(value); + public static bool IsComplexNumber(T value) => T.IsComplexNumber(value); + public static bool IsEvenInteger(T value) => T.IsEvenInteger(value); + public static bool IsFinite(T value) => T.IsFinite(value); + public static bool IsImaginaryNumber(T value) => T.IsImaginaryNumber(value); + public static bool IsInfinity(T value) => T.IsInfinity(value); + public static bool IsInteger(T value) => T.IsInteger(value); + public static bool IsNaN(T value) => T.IsNaN(value); + public static bool IsNegative(T value) => T.IsNegative(value); + public static bool IsNegativeInfinity(T value) => T.IsNegativeInfinity(value); + public static bool IsNormal(T value) => T.IsNormal(value); + public static bool IsOddInteger(T value) => T.IsOddInteger(value); + public static bool IsPositive(T value) => T.IsPositive(value); + public static bool IsPositiveInfinity(T value) => T.IsPositiveInfinity(value); + public static bool IsRealNumber(T value) => T.IsRealNumber(value); + public static bool IsSubnormal(T value) => T.IsSubnormal(value); + public static bool IsZero(T value) => T.IsZero(value); + public static T MaxMagnitude(T x, T y) => T.MaxMagnitude(x, y); + public static T MaxMagnitudeNumber(T x, T y) => T.MaxMagnitudeNumber(x, y); + public static T MinMagnitude(T x, T y) => T.MinMagnitude(x, y); + public static T MinMagnitudeNumber(T x, T y) => T.MinMagnitudeNumber(x, y); + } +#endif +} diff --git a/src/EntityFrameworkApp/EntityFrameworkApp.csproj b/src/EntityFrameworkApp/EntityFrameworkApp.csproj index e68d3c8..a57606c 100644 --- a/src/EntityFrameworkApp/EntityFrameworkApp.csproj +++ b/src/EntityFrameworkApp/EntityFrameworkApp.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 enable enable diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index 33a1226..ae2ac00 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -161,6 +161,37 @@ internal enum UnitGenerateArithmeticOperator Increment = 1 << 4, Decrement = 1 << 5, } + +#if NET7_0_OR_GREATER + internal static class NumberProxy where T : INumber + { + public static T One => T.One; + public static int Radix => T.Radix; + public static T Zero => T.Zero; + public static T Abs(T value) => T.Abs(value); + public static bool IsCanonical(T value) => T.IsCanonical(value); + public static bool IsComplexNumber(T value) => T.IsComplexNumber(value); + public static bool IsEvenInteger(T value) => T.IsEvenInteger(value); + public static bool IsFinite(T value) => T.IsFinite(value); + public static bool IsImaginaryNumber(T value) => T.IsImaginaryNumber(value); + public static bool IsInfinity(T value) => T.IsInfinity(value); + public static bool IsInteger(T value) => T.IsInteger(value); + public static bool IsNaN(T value) => T.IsNaN(value); + public static bool IsNegative(T value) => T.IsNegative(value); + public static bool IsNegativeInfinity(T value) => T.IsNegativeInfinity(value); + public static bool IsNormal(T value) => T.IsNormal(value); + public static bool IsOddInteger(T value) => T.IsOddInteger(value); + public static bool IsPositive(T value) => T.IsPositive(value); + public static bool IsPositiveInfinity(T value) => T.IsPositiveInfinity(value); + public static bool IsRealNumber(T value) => T.IsRealNumber(value); + public static bool IsSubnormal(T value) => T.IsSubnormal(value); + public static bool IsZero(T value) => T.IsZero(value); + public static T MaxMagnitude(T x, T y) => T.MaxMagnitude(x, y); + public static T MaxMagnitudeNumber(T x, T y) => T.MaxMagnitudeNumber(x, y); + public static T MinMagnitude(T x, T y) => T.MinMagnitude(x, y); + public static T MinMagnitudeNumber(T x, T y) => T.MinMagnitudeNumber(x, y); + } +#endif } """; @@ -240,15 +271,19 @@ readonly partial struct {{unitTypeName}} sb.AppendLine($$""" #if NET7_0_OR_GREATER : INumber<{{unitTypeName}}> +#else + : IEquatable<{{unitTypeName}}> + , IComparable<{{unitTypeName}}> + , IComparable #endif """); } else { sb.AppendLine($$""" - : IEquatable<{{{unitTypeName}}>"); + : IEquatable<{{{unitTypeName}}> #if NET7_0_OR_GREATER - , IEqualityOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> + , IEqualityOperators<{{unitTypeName}}, {{unitTypeName}}, bool> #endif """); if (prop.HasFlag(UnitGenerateOptions.Comparable)) @@ -256,6 +291,14 @@ readonly partial struct {{unitTypeName}} sb.AppendLine($$""" , IComparable<{{unitTypeName}}> """); + if (!prop.HasFlag(UnitGenerateOptions.WithoutComparisonOperator)) + { + sb.AppendLine($$""" +#if NET7_0_OR_GREATER + , IComparisonOperators<{{unitTypeName}}, {{unitTypeName}}, bool> +#endif +"""); + } } if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) { @@ -264,14 +307,12 @@ readonly partial struct {{unitTypeName}} { sb.AppendLine($$""" , IAdditionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> - , IUnaryPlusOperators<{{unitTypeName}}, {{unitTypeName}}> """); } if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Subtraction)) { sb.AppendLine($$""" , ISubtractionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> - , IUnaryNegationOperators<{{unitTypeName}}, {{unitTypeName}}> """); } if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition | @@ -298,6 +339,8 @@ readonly partial struct {{unitTypeName}} { sb.AppendLine($$""" , IMultiplicativeIdentity<{{unitTypeName}}, {{unitTypeName}}> + , IUnaryPlusOperators<{{unitTypeName}}, {{unitTypeName}}> + , IUnaryNegationOperators<{{unitTypeName}}, {{unitTypeName}}> """); } if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Increment)) @@ -391,12 +434,12 @@ public override bool Equals(object obj) return value.Equals(obj); } - public static bool operator ==(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool operator ==({{unitTypeName}} x, {{unitTypeName}} y) { return x.value.Equals(y.value); } - public static bool operator !=(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool operator !=({{unitTypeName}} x, {{unitTypeName}} y) { return !x.value.Equals(y.value); } @@ -572,18 +615,17 @@ public static bool TryParse(string s, out {{unitTypeName}} result) sb.AppendLine($$""" #if NET7_0_OR_GREATER public static {{unitTypeName}} AdditiveIdentity => {{innerTypeName}}.AdditiveIdentity; - #endif -"""); +"""); if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition)) { sb.AppendLine($$""" - public static {{unitTypeName}} operator +(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static {{unitTypeName}} operator +({{unitTypeName}} x, {{unitTypeName}} y) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value + y.value)); + return new {{unitTypeName}}(x.value + y.value); } } @@ -592,11 +634,11 @@ public static bool TryParse(string s, out {{unitTypeName}} result) if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Subtraction)) { sb.AppendLine($$""" - public static {{unitTypeName}} operator -(in {{unitTypeName}} x, in {{innerTypeName}} y) + public static {{unitTypeName}} operator -({{unitTypeName}} x, {{unitTypeName}} y) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value - y)); + return new {{unitTypeName}}(x.value - y.value); } } @@ -610,17 +652,19 @@ public static bool TryParse(string s, out {{unitTypeName}} result) sb.AppendLine($$""" #if NET7_0_OR_GREATER public static {{unitTypeName}} MultiplicativeIdentity => {{innerTypeName}}.MultiplicativeIdentity; - #endif + public static {{unitTypeName}} operator +({{unitTypeName}} value) => new(+value.value); + public static {{unitTypeName}} operator -({{unitTypeName}} value) => new(-value.value); + """); if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply)) { sb.AppendLine($$""" - public static {{unitTypeName}} operator *(in {{unitTypeName}} x, in {{innerTypeName}} y) + public static {{unitTypeName}} operator *({{unitTypeName}} x, {{unitTypeName}} y) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value * y)); + return new {{unitTypeName}}(x.value * y.value); } } @@ -630,11 +674,11 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { sb.AppendLine($$""" - public static {{unitTypeName}} operator /(in {{unitTypeName}} x, in {{innerTypeName}} y) + public static {{unitTypeName}} operator /({{unitTypeName}} x, {{unitTypeName}} y) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value / y)); + return new {{unitTypeName}}(x.value / y.value); } } @@ -645,7 +689,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Increment)) { sb.AppendLine($$""" - public static {{unitTypeName}} operator ++(in {{unitTypeName}} x) + public static {{unitTypeName}} operator ++({{unitTypeName}} x) { checked { @@ -658,7 +702,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Decrement)) { sb.AppendLine($$""" - public static {{unitTypeName}} operator --(in {{unitTypeName}} x) + public static {{unitTypeName}} operator --({{unitTypeName}} x) { checked { @@ -679,29 +723,33 @@ public int CompareTo({{unitTypeName}} other) { return value.CompareTo(other.value); } - + + public int CompareTo(object? obj) + { + return value.CompareTo(obj); + } """); } if (prop.IsNumber() || (prop.HasFlag(UnitGenerateOptions.Comparable) && !prop.HasFlag(UnitGenerateOptions.WithoutComparisonOperator))) { sb.AppendLine($$""" - public static bool operator >(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool operator >({{unitTypeName}} x, {{unitTypeName}} y) { return x.value > y.value; } - public static bool operator <(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool operator <({{unitTypeName}} x, {{unitTypeName}} y) { return x.value < y.value; } - public static bool operator >=(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool operator >=({{unitTypeName}} x, {{unitTypeName}} y) { return x.value >= y.value; } - public static bool operator <=(in {{unitTypeName}} x, in {{unitTypeName}} y) + public static bool operator <=({{unitTypeName}} x, {{unitTypeName}} y) { return x.value <= y.value; } @@ -712,7 +760,7 @@ public int CompareTo({{unitTypeName}} other) if (prop.IsNumber()) { sb.AppendLine($$""" - public static {{unitTypeName}} operator %({{unitTypeName}} x, {{unitTypeName}} y) => x.value % y.value; + public static {{unitTypeName}} operator %({{unitTypeName}} x, {{unitTypeName}} y) => new {{unitTypeName}}(x.value % y.value); // IFormattable @@ -758,102 +806,62 @@ public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out return false; } - // INumber - - public static {{unitTypeName}} One => {{innerTypeName}}.One; - public static int Radix => {{innerTypeName}}.Radix; - public static {{unitTypeName}} Zero => {{innerTypeName}}.Zero; + // INumberBase - public static {{unitTypeName}} Abs({{unitTypeName}} value) => {{innerTypeName}}.Abs(value.value); - - public static bool IsCanonical({{unitTypeName}} value) => {{innerTypeName}}.IsCanonical(value.value); - - public static bool IsComplexNumber({{unitTypeName}} value) => {{innerTypeName}}.IsComplexNumber(value.value); - - public static bool IsEvenInteger({{unitTypeName}} value) => {{innerTypeName}}.IsEventInteger(value.value); - - public static bool IsFinite({{unitTypeName}} value) => {{innerTypeName}}.IsFinite(value.value); - - public static bool IsImaginaryNumber({{unitTypeName}} value) => {{innerTypeName}}.IsImaginaryNumber(value.value); - - public static bool IsInfinity({{unitTypeName}} value) => {{innerTypeName}}.IsInfinity(value.value); - - public static bool IsInteger({{unitTypeName}} value) => {{innerTypeName}}.IsInteger(value.value); - - public static bool IsNaN({{unitTypeName}} value) => {{innerTypeName}}.IsNaN(value.value); - - public static bool IsNegative({{unitTypeName}} value) => {{innerTypeName}}.IsNegative(value.value); - - public static bool IsNegativeInfinity({{unitTypeName}} value) => {{innerTypeName}}.IsNegativeInfinity(value.value); - - public static bool IsNormal({{unitTypeName}} value) => {{innerTypeName}}.IsNormal(value.value); - - public static bool IsOddInteger({{unitTypeName}} value) => {{innerTypeName}}.IsOddInteger(value.value); - - public static bool IsPositive({{unitTypeName}} value) => {{innerTypeName}}.IsPositive(value.value); - - public static bool IsPositiveInfinity({{unitTypeName}} value) => {{innerTypeName}}.IsPositiveInfinity(value.value); - - public static bool IsRealNumber({{unitTypeName}} value) => {{innerTypeName}}.IsRealNumber(value.value); - - public static bool IsSubnormal({{unitTypeName}} value) => {{innerTypeName}}.IsSubnormal(value.value); - - public static bool IsZero({{unitTypeName}} value) => {{innerTypeName}}.IsZero(value.value); - - public static {{unitTypeName}} MaxMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => {{innerTypeName}}.MaxMagnitude(x.value, y.value); - - public static {{unitTypeName}} MaxMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => {{innerTypeName}}.MaxMagnitudeNumber(x.value, y.value); - - public static {{unitTypeName}} MinMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => {{innerTypeName}}.MinMagnitude(x.value, y.value); - - public static {{unitTypeName}} MinMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => {{innerTypeName}}.MinMagnitudeNumber(x.value, y.value); + public static {{unitTypeName}} One => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.One); + public static int Radix => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.Radix; + public static {{unitTypeName}} Zero => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.Zero); + public static {{unitTypeName}} Abs({{unitTypeName}} value) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.Abs(value.value)); + public static bool IsCanonical({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsCanonical(value.value); + public static bool IsComplexNumber({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsComplexNumber(value.value); + public static bool IsEvenInteger({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsEventInteger(value.value); + public static bool IsFinite({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsFinite(value.value); + public static bool IsImaginaryNumber({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsImaginaryNumber(value.value); + public static bool IsInfinity({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsInfinity(value.value); + public static bool IsInteger({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsInteger(value.value); + public static bool IsNaN({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsNaN(value.value); + public static bool IsNegative({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsNegative(value.value); + public static bool IsNegativeInfinity({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsNegativeInfinity(value.value); + public static bool IsNormal({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsNormal(value.value); + public static bool IsOddInteger({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsOddInteger(value.value); + public static bool IsPositive({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsPositive(value.value); + public static bool IsPositiveInfinity({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsPositiveInfinity(value.value); + public static bool IsRealNumber({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsRealNumber(value.value); + public static bool IsSubnormal({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsSubnormal(value.value); + public static bool IsZero({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsZero(value.value); + public static {{unitTypeName}} MaxMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MaxMagnitude(x.value, y.value)); + public static {{unitTypeName}} MaxMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MaxMagnitudeNumber(x.value, y.value)); + public static {{unitTypeName}} MinMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MinMagnitude(x.value, y.value)); + public static {{unitTypeName}} MinMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MinMagnitudeNumber(x.value, y.value)); public static bool TryConvertFromChecked(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - if ({{innerTypeName}}.TryConvertFromChecked(value, out var innerResult)) - { - result = new {{unitTypeName}}(innerResult); - return true; - } - result = default; - return false; + throw new NotSupportedException(); } public static bool TryConvertFromSaturating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - if ({{innerTypeName}}.TryConvertFromSaturating(value, out var innerResult) - { - result = new {{unitTypeName}}(innerResult); - return true; - } - result = default; - return false; + throw new NotSupportedException(); } public static bool TryConvertFromTruncating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - if ({{innerTypeName}}.TryConvertFromTruncating(value, out var innerResult)) - { - result = new {{unitTypeName}}(innerResult); - return true; - } - result = default; - return false; + throw new NotSupportedException(); } public static bool TryConvertToChecked({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return ({{innerTypeName}}.TryConvertToChecked(value.value, out result)); + throw new NotSupportedException(); } public static bool TryConvertToSaturating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return {{innerTypeName}}.TryConvertToSaturating(value.value, out result); + throw new NotSupportedException(); } public static bool TryConvertToTruncating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return {{innerTypeName}}.TryConvertToTruncating(value.value, out result); + throw new NotSupportedException(); } public static {{unitTypeName}} Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); @@ -1171,7 +1179,8 @@ public bool IsNumber() => HasFlag(UnitGenerateOptions.ArithmeticOperator) && public bool HasArithmeticOperator(UnitGenerateArithmeticOperator op) { return HasFlag(UnitGenerateOptions.ArithmeticOperator) && - ArithmeticOperator.HasFlag(op); + (ArithmeticOperator == UnitGenerateArithmeticOperator.Number || + ArithmeticOperator.HasFlag(op)); } public DbType GetDbType() From b88b147bfd69c8260927b447bf1b1018763a7cca Mon Sep 17 00:00:00 2001 From: hadashiA Date: Tue, 15 Aug 2023 17:10:40 +0900 Subject: [PATCH 03/12] Fix some compilation errors --- sandbox/ConsoleApp/Others.cs | 6 --- src/UnitGenerator/SourceGenerator.cs | 58 ++++++++++++++++------------ 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/sandbox/ConsoleApp/Others.cs b/sandbox/ConsoleApp/Others.cs index c1b68b7..de38d13 100644 --- a/sandbox/ConsoleApp/Others.cs +++ b/sandbox/ConsoleApp/Others.cs @@ -5,17 +5,11 @@ namespace ConsoleApp { - internal static class NumberProxy where T : INumber - { - private static T One() => T.One; - } - [UnitOf(typeof(Guid), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.Validate | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter)] public readonly partial struct GD { private partial void Validate() { - UnitGenerator.NumberProxy.One(); _ = AsPrimitive(); } } diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index ae2ac00..e35a947 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -110,8 +110,10 @@ private void SetDefaultAttribute(GeneratorPostInitializationContext context) // #pragma warning disable CS8669 #pragma warning disable CS8625 -#nullable enable using System; +#if NET7_0_OR_GREATER +using System.Numerics; +#endif namespace UnitGenerator { @@ -169,6 +171,8 @@ internal static class NumberProxy where T : INumber public static int Radix => T.Radix; public static T Zero => T.Zero; public static T Abs(T value) => T.Abs(value); + public static T AdditiveIdentity => T.AdditiveIdentity; + public static T MultiplicativeIdentity => T.MultiplicativeIdentity; public static bool IsCanonical(T value) => T.IsCanonical(value); public static bool IsComplexNumber(T value) => T.IsComplexNumber(value); public static bool IsEvenInteger(T value) => T.IsEvenInteger(value); @@ -209,19 +213,13 @@ private string GenerateType(INamedTypeSymbol symbol, UnitOfAttributeProperty pro // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // #pragma warning disable CS8669 -#nullable enable using System; - -"""); - if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) - { - sb.AppendLine(""" +using System.Globalization; #if NET7_0_OR_GREATER using System.Numerics; -using System.Globalization; #endif + """); - } if (prop.HasFlag(UnitGenerateOptions.MessagePackFormatter)) { sb.AppendLine(""" @@ -281,7 +279,7 @@ readonly partial struct {{unitTypeName}} else { sb.AppendLine($$""" - : IEquatable<{{{unitTypeName}}> + : IEquatable<{{unitTypeName}}> #if NET7_0_OR_GREATER , IEqualityOperators<{{unitTypeName}}, {{unitTypeName}}, bool> #endif @@ -393,6 +391,7 @@ readonly partial struct {{unitTypeName}} """); } + if (prop.HasFlag(UnitGenerateOptions.Validate)) { sb.AppendLine(""" @@ -614,7 +613,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { sb.AppendLine($$""" #if NET7_0_OR_GREATER - public static {{unitTypeName}} AdditiveIdentity => {{innerTypeName}}.AdditiveIdentity; + public static {{unitTypeName}} AdditiveIdentity => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.AdditiveIdentity); #endif """); @@ -625,7 +624,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { checked { - return new {{unitTypeName}}(x.value + y.value); + return new {{unitTypeName}}(({{innerTypeName}})(x.value + y.value)); } } @@ -638,7 +637,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { checked { - return new {{unitTypeName}}(x.value - y.value); + return new {{unitTypeName}}(({{innerTypeName}})(x.value - y.value)); } } @@ -651,10 +650,10 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { sb.AppendLine($$""" #if NET7_0_OR_GREATER - public static {{unitTypeName}} MultiplicativeIdentity => {{innerTypeName}}.MultiplicativeIdentity; + public static {{unitTypeName}} MultiplicativeIdentity => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MultiplicativeIdentity); #endif - public static {{unitTypeName}} operator +({{unitTypeName}} value) => new(+value.value); - public static {{unitTypeName}} operator -({{unitTypeName}} value) => new(-value.value); + public static {{unitTypeName}} operator +({{unitTypeName}} value) => new(({{innerTypeName}})(+value.value)); + public static {{unitTypeName}} operator -({{unitTypeName}} value) => new(({{innerTypeName}})(-value.value)); """); if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply)) @@ -664,7 +663,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { checked { - return new {{unitTypeName}}(x.value * y.value); + return new {{unitTypeName}}(({{innerTypeName}})(x.value * y.value)); } } @@ -678,7 +677,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { checked { - return new {{unitTypeName}}(x.value / y.value); + return new {{unitTypeName}}(({{innerTypeName}})(x.value / y.value)); } } @@ -693,7 +692,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value + 1)); + return new {{unitTypeName}}(({{innerTypeName}})(({{innerTypeName}})(x.value + 1))); } } @@ -706,7 +705,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { checked { - return new {{unitTypeName}}(({{innerTypeName}})(x.value - 1)); + return new {{unitTypeName}}(({{innerTypeName}})(({{innerTypeName}})(x.value - 1))); } } @@ -726,7 +725,16 @@ public int CompareTo({{unitTypeName}} other) public int CompareTo(object? obj) { - return value.CompareTo(obj); + if (obj == null) + { + return 1; + } + + if (obj is {{unitTypeName}} other) + { + return value.CompareTo(other.value); + } + throw new ArgumentException(); } """); } @@ -760,7 +768,7 @@ public int CompareTo(object? obj) if (prop.IsNumber()) { sb.AppendLine($$""" - public static {{unitTypeName}} operator %({{unitTypeName}} x, {{unitTypeName}} y) => new {{unitTypeName}}(x.value % y.value); + public static {{unitTypeName}} operator %({{unitTypeName}} x, {{unitTypeName}} y) => new {{unitTypeName}}(({{innerTypeName}})(x.value % y.value)); // IFormattable @@ -814,7 +822,7 @@ public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out public static {{unitTypeName}} Abs({{unitTypeName}} value) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.Abs(value.value)); public static bool IsCanonical({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsCanonical(value.value); public static bool IsComplexNumber({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsComplexNumber(value.value); - public static bool IsEvenInteger({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsEventInteger(value.value); + public static bool IsEvenInteger({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsEvenInteger(value.value); public static bool IsFinite({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsFinite(value.value); public static bool IsImaginaryNumber({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsImaginaryNumber(value.value); public static bool IsInfinity({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsInfinity(value.value); @@ -1171,11 +1179,11 @@ struct UnitOfAttributeProperty public bool IsUlid() => TypeName is "Ulid" or "System.Ulid"; public bool IsGuid() => TypeName is "Guid" or "System.Guid"; + public bool HasFlag(UnitGenerateOptions options) => Options.HasFlag(options); + public bool IsNumber() => HasFlag(UnitGenerateOptions.ArithmeticOperator) && ArithmeticOperator == UnitGenerateArithmeticOperator.Number; - public bool HasFlag(UnitGenerateOptions options) => Options.HasFlag(options); - public bool HasArithmeticOperator(UnitGenerateArithmeticOperator op) { return HasFlag(UnitGenerateOptions.ArithmeticOperator) && From a8e5e5d4cfc766974dadf959596e03d706b204bd Mon Sep 17 00:00:00 2001 From: hadashiA Date: Tue, 15 Aug 2023 17:15:18 +0900 Subject: [PATCH 04/12] Rename helper class --- src/UnitGenerator/SourceGenerator.cs | 57 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index e35a947..241b5e8 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -165,7 +165,7 @@ internal enum UnitGenerateArithmeticOperator } #if NET7_0_OR_GREATER - internal static class NumberProxy where T : INumber + internal static class AsNumberT> where T : INumber { public static T One => T.One; public static int Radix => T.Radix; @@ -613,7 +613,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { sb.AppendLine($$""" #if NET7_0_OR_GREATER - public static {{unitTypeName}} AdditiveIdentity => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.AdditiveIdentity); + public static {{unitTypeName}} AdditiveIdentity => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.AdditiveIdentity); #endif """); @@ -650,7 +650,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { sb.AppendLine($$""" #if NET7_0_OR_GREATER - public static {{unitTypeName}} MultiplicativeIdentity => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MultiplicativeIdentity); + public static {{unitTypeName}} MultiplicativeIdentity => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MultiplicativeIdentity); #endif public static {{unitTypeName}} operator +({{unitTypeName}} value) => new(({{innerTypeName}})(+value.value)); public static {{unitTypeName}} operator -({{unitTypeName}} value) => new(({{innerTypeName}})(-value.value)); @@ -781,7 +781,6 @@ public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan { return value.TryFormat(destination, out charsWritten, format, provider); } - #endif #if NET7_0_OR_GREATER // IParsable @@ -816,31 +815,31 @@ public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out // INumberBase - public static {{unitTypeName}} One => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.One); - public static int Radix => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.Radix; - public static {{unitTypeName}} Zero => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.Zero); - public static {{unitTypeName}} Abs({{unitTypeName}} value) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.Abs(value.value)); - public static bool IsCanonical({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsCanonical(value.value); - public static bool IsComplexNumber({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsComplexNumber(value.value); - public static bool IsEvenInteger({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsEvenInteger(value.value); - public static bool IsFinite({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsFinite(value.value); - public static bool IsImaginaryNumber({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsImaginaryNumber(value.value); - public static bool IsInfinity({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsInfinity(value.value); - public static bool IsInteger({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsInteger(value.value); - public static bool IsNaN({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsNaN(value.value); - public static bool IsNegative({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsNegative(value.value); - public static bool IsNegativeInfinity({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsNegativeInfinity(value.value); - public static bool IsNormal({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsNormal(value.value); - public static bool IsOddInteger({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsOddInteger(value.value); - public static bool IsPositive({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsPositive(value.value); - public static bool IsPositiveInfinity({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsPositiveInfinity(value.value); - public static bool IsRealNumber({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsRealNumber(value.value); - public static bool IsSubnormal({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsSubnormal(value.value); - public static bool IsZero({{unitTypeName}} value) => global::UnitGenerator.NumberProxy<{{innerTypeName}}>.IsZero(value.value); - public static {{unitTypeName}} MaxMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MaxMagnitude(x.value, y.value)); - public static {{unitTypeName}} MaxMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MaxMagnitudeNumber(x.value, y.value)); - public static {{unitTypeName}} MinMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MinMagnitude(x.value, y.value)); - public static {{unitTypeName}} MinMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.NumberProxy<{{innerTypeName}}>.MinMagnitudeNumber(x.value, y.value)); + public static {{unitTypeName}} One => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.One); + public static int Radix => global::UnitGenerator.AsNumber{{innerTypeName}}>.Radix; + public static {{unitTypeName}} Zero => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.Zero); + public static {{unitTypeName}} Abs({{unitTypeName}} value) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.Abs(value.value)); + public static bool IsCanonical({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsCanonical(value.value); + public static bool IsComplexNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsComplexNumber(value.value); + public static bool IsEvenInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsEvenInteger(value.value); + public static bool IsFinite({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsFinite(value.value); + public static bool IsImaginaryNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsImaginaryNumber(value.value); + public static bool IsInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsInfinity(value.value); + public static bool IsInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsInteger(value.value); + public static bool IsNaN({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsNaN(value.value); + public static bool IsNegative({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsNegative(value.value); + public static bool IsNegativeInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsNegativeInfinity(value.value); + public static bool IsNormal({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsNormal(value.value); + public static bool IsOddInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsOddInteger(value.value); + public static bool IsPositive({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsPositive(value.value); + public static bool IsPositiveInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsPositiveInfinity(value.value); + public static bool IsRealNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsRealNumber(value.value); + public static bool IsSubnormal({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsSubnormal(value.value); + public static bool IsZero({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsZero(value.value); + public static {{unitTypeName}} MaxMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MaxMagnitude(x.value, y.value)); + public static {{unitTypeName}} MaxMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MaxMagnitudeNumber(x.value, y.value)); + public static {{unitTypeName}} MinMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MinMagnitude(x.value, y.value)); + public static {{unitTypeName}} MinMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MinMagnitudeNumber(x.value, y.value)); public static bool TryConvertFromChecked(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { From 328544b1e4ae71eed89505ecb341bbd09cd3bdd0 Mon Sep 17 00:00:00 2001 From: hadashiA Date: Tue, 15 Aug 2023 20:43:15 +0900 Subject: [PATCH 05/12] TryConvert* --- sandbox/ConsoleApp/AllPrimitives.cs | 20 +-- .../UnitOfAttribute.cs | 2 +- src/UnitGenerator/SourceGenerator.cs | 156 ++++++++++++++---- 3 files changed, 133 insertions(+), 45 deletions(-) diff --git a/sandbox/ConsoleApp/AllPrimitives.cs b/sandbox/ConsoleApp/AllPrimitives.cs index 9c69366..b16deb6 100644 --- a/sandbox/ConsoleApp/AllPrimitives.cs +++ b/sandbox/ConsoleApp/AllPrimitives.cs @@ -25,7 +25,7 @@ private partial void Validate() } } - [UnitOf(typeof(int), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(int), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct T { private partial void Validate() @@ -34,7 +34,7 @@ private partial void Validate() } } - [UnitOf(typeof(uint), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(uint), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct B { private partial void Validate() @@ -43,7 +43,7 @@ private partial void Validate() } } - [UnitOf(typeof(short), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(short), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct C { private partial void Validate() @@ -52,7 +52,7 @@ private partial void Validate() } } - [UnitOf(typeof(ushort), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(ushort), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct D { private partial void Validate() @@ -61,7 +61,7 @@ private partial void Validate() } } - [UnitOf(typeof(byte), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(byte), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct E { private partial void Validate() @@ -70,7 +70,7 @@ private partial void Validate() } } - [UnitOf(typeof(sbyte), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(sbyte), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct F { private partial void Validate() @@ -79,7 +79,7 @@ private partial void Validate() } } - [UnitOf(typeof(float), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(float), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct G { private partial void Validate() @@ -88,7 +88,7 @@ private partial void Validate() } } - [UnitOf(typeof(double), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(double), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct H { private partial void Validate() @@ -97,7 +97,7 @@ private partial void Validate() } } - [UnitOf(typeof(decimal), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(decimal), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct I { private partial void Validate() @@ -106,7 +106,7 @@ private partial void Validate() } } - [UnitOf(typeof(float), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] + [UnitOf(typeof(float), UnitGenerateOptions.ParseMethod | UnitGenerateOptions.MinMaxMethod | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.Validate | UnitGenerateOptions.JsonConverter | UnitGenerateOptions.MessagePackFormatter | UnitGenerateOptions.DapperTypeHandler | UnitGenerateOptions.EntityFrameworkValueConverter | UnitGenerateOptions.JsonConverterDictionaryKeySupport)] public readonly partial struct J { private partial void Validate() diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs index bfe259d..d230a3e 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs @@ -56,7 +56,7 @@ internal enum UnitGenerateArithmeticOperator } #if NET7_0_OR_GREATER - internal static class NumberProxy where T : INumber + internal static class AsNumber where T : INumber { public static T One => T.One; public static int Radix => T.Radix; diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index 241b5e8..b43ade5 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -165,7 +165,7 @@ internal enum UnitGenerateArithmeticOperator } #if NET7_0_OR_GREATER - internal static class AsNumberT> where T : INumber + internal static class AsNumber where T : INumber { public static T One => T.One; public static int Radix => T.Radix; @@ -194,6 +194,12 @@ internal static class AsNumberT> where T : INumber public static T MaxMagnitudeNumber(T x, T y) => T.MaxMagnitudeNumber(x, y); public static T MinMagnitude(T x, T y) => T.MinMagnitude(x, y); public static T MinMagnitudeNumber(T x, T y) => T.MinMagnitudeNumber(x, y); + public static bool TryConvertFromChecked(TOther value, out T result) => T.TryConvertFromChecked(value, out result); + public static bool TryConvertFromSaturating(TOther value, out T result) => T.TryConvertFromSaturating(value, out result); + public static bool TryConvertFromTruncating(TOther value, out T result) => T.TryConvertFromTruncating(value, out result); + public static bool TryConvertToChecked(T value, out TOther result) => T.TryConvertToChecked(value, out result); + public static bool TryConvertToSaturating(T value, out TOther result) => T.TryConvertToSaturating(value, out result); + public static bool TryConvertToTruncating(T value, out TOther result) => T.TryConvertToTruncating(value, out result); } #endif } @@ -613,7 +619,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { sb.AppendLine($$""" #if NET7_0_OR_GREATER - public static {{unitTypeName}} AdditiveIdentity => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.AdditiveIdentity); + public static {{unitTypeName}} AdditiveIdentity => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.AdditiveIdentity); #endif """); @@ -650,7 +656,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) { sb.AppendLine($$""" #if NET7_0_OR_GREATER - public static {{unitTypeName}} MultiplicativeIdentity => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MultiplicativeIdentity); + public static {{unitTypeName}} MultiplicativeIdentity => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MultiplicativeIdentity); #endif public static {{unitTypeName}} operator +({{unitTypeName}} value) => new(({{innerTypeName}})(+value.value)); public static {{unitTypeName}} operator -({{unitTypeName}} value) => new(({{innerTypeName}})(-value.value)); @@ -713,6 +719,63 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } // End ArithmeticOperator + if (prop.HasFlag(UnitGenerateOptions.ValueArithmeticOperator)) + { + if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperator.Addition)) + { + sb.AppendLine($$""" + public static {{unitTypeName}} operator +({{unitTypeName}} x, {{innerTypeName}} y) + { + checked + { + return new {{unitTypeName}}(({{innerTypeName}})(x.value + y)); + } + } + +"""); + } + if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperator.Subtraction)) + { + sb.AppendLine($$""" + public static {{unitTypeName}} operator -({{unitTypeName}} x, {{innerTypeName}} y) + { + checked + { + return new {{unitTypeName}}(({{innerTypeName}})(x.value - y)); + } + } + +"""); + } + if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperator.Multiply)) + { + sb.AppendLine($$""" + public static {{unitTypeName}} operator *({{unitTypeName}} x, {{innerTypeName}} y) + { + checked + { + return new {{unitTypeName}}(({{innerTypeName}})(x.value * y)); + } + } + +"""); + } + if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperator.Division)) + { + sb.AppendLine($$""" + + public static {{unitTypeName}} operator /({{unitTypeName}} x, {{innerTypeName}} y) + { + checked + { + return new {{unitTypeName}}(({{innerTypeName}})(x.value / y)); + } + } + +"""); + } + } // End ValueArithmeticOperator + if (prop.IsNumber() || prop.HasFlag(UnitGenerateOptions.Comparable)) { sb.AppendLine($$""" @@ -815,60 +878,78 @@ public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out // INumberBase - public static {{unitTypeName}} One => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.One); - public static int Radix => global::UnitGenerator.AsNumber{{innerTypeName}}>.Radix; - public static {{unitTypeName}} Zero => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.Zero); - public static {{unitTypeName}} Abs({{unitTypeName}} value) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.Abs(value.value)); - public static bool IsCanonical({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsCanonical(value.value); - public static bool IsComplexNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsComplexNumber(value.value); - public static bool IsEvenInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsEvenInteger(value.value); - public static bool IsFinite({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsFinite(value.value); - public static bool IsImaginaryNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsImaginaryNumber(value.value); - public static bool IsInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsInfinity(value.value); - public static bool IsInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsInteger(value.value); - public static bool IsNaN({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsNaN(value.value); - public static bool IsNegative({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsNegative(value.value); - public static bool IsNegativeInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsNegativeInfinity(value.value); - public static bool IsNormal({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsNormal(value.value); - public static bool IsOddInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsOddInteger(value.value); - public static bool IsPositive({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsPositive(value.value); - public static bool IsPositiveInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsPositiveInfinity(value.value); - public static bool IsRealNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsRealNumber(value.value); - public static bool IsSubnormal({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsSubnormal(value.value); - public static bool IsZero({{unitTypeName}} value) => global::UnitGenerator.AsNumber{{innerTypeName}}>.IsZero(value.value); - public static {{unitTypeName}} MaxMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MaxMagnitude(x.value, y.value)); - public static {{unitTypeName}} MaxMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MaxMagnitudeNumber(x.value, y.value)); - public static {{unitTypeName}} MinMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MinMagnitude(x.value, y.value)); - public static {{unitTypeName}} MinMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber{{innerTypeName}}>.MinMagnitudeNumber(x.value, y.value)); + public static {{unitTypeName}} One => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.One); + public static int Radix => global::UnitGenerator.AsNumber<{{innerTypeName}}>.Radix; + public static {{unitTypeName}} Zero => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.Zero); + public static {{unitTypeName}} Abs({{unitTypeName}} value) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.Abs(value.value)); + public static bool IsCanonical({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsCanonical(value.value); + public static bool IsComplexNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsComplexNumber(value.value); + public static bool IsEvenInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsEvenInteger(value.value); + public static bool IsFinite({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsFinite(value.value); + public static bool IsImaginaryNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsImaginaryNumber(value.value); + public static bool IsInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsInfinity(value.value); + public static bool IsInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsInteger(value.value); + public static bool IsNaN({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsNaN(value.value); + public static bool IsNegative({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsNegative(value.value); + public static bool IsNegativeInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsNegativeInfinity(value.value); + public static bool IsNormal({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsNormal(value.value); + public static bool IsOddInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsOddInteger(value.value); + public static bool IsPositive({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsPositive(value.value); + public static bool IsPositiveInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsPositiveInfinity(value.value); + public static bool IsRealNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsRealNumber(value.value); + public static bool IsSubnormal({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsSubnormal(value.value); + public static bool IsZero({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsZero(value.value); + public static {{unitTypeName}} MaxMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MaxMagnitude(x.value, y.value)); + public static {{unitTypeName}} MaxMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MaxMagnitudeNumber(x.value, y.value)); + public static {{unitTypeName}} MinMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MinMagnitude(x.value, y.value)); + public static {{unitTypeName}} MinMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MinMagnitudeNumber(x.value, y.value)); public static bool TryConvertFromChecked(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - throw new NotSupportedException(); + if (global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertFromChecked(value, out var innerResult)) + { + result = new {{unitTypeName}}(innerResult); + return true; + } + result = default; + return false; } public static bool TryConvertFromSaturating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - throw new NotSupportedException(); + if (global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertFromSaturating(value, out var innerResult)) + { + result = new {{unitTypeName}}(innerResult); + return true; + } + result = default; + return false; } public static bool TryConvertFromTruncating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - throw new NotSupportedException(); + if (global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertFromTruncating(value, out var innerResult)) + { + result = new {{unitTypeName}}(innerResult); + return true; + } + result = default; + return false; } public static bool TryConvertToChecked({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - throw new NotSupportedException(); + return global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertToChecked(value.value, out result); } public static bool TryConvertToSaturating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - throw new NotSupportedException(); + return global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertToSaturating(value.value, out result); } public static bool TryConvertToTruncating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - throw new NotSupportedException(); + return global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertToTruncating(value.value, out result); } public static {{unitTypeName}} Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); @@ -1190,6 +1271,13 @@ public bool HasArithmeticOperator(UnitGenerateArithmeticOperator op) ArithmeticOperator.HasFlag(op)); } + public bool HasValueArithmeticOperator(UnitGenerateArithmeticOperator op) + { + return HasFlag(UnitGenerateOptions.ValueArithmeticOperator) && + (ArithmeticOperator == UnitGenerateArithmeticOperator.Number || + ArithmeticOperator.HasFlag(op)); + } + public DbType GetDbType() { return TypeName switch From 5e78d03528b06b06ac7094669e224d7c103c9539 Mon Sep 17 00:00:00 2001 From: hadashiA Date: Wed, 16 Aug 2023 11:54:43 +0900 Subject: [PATCH 06/12] Add samples about arithmetic-operator separately --- sandbox/ConsoleApp/Operators.cs | 37 +++++ sandbox/ConsoleApp/Others.cs | 145 ------------------ .../FileGenerate.A.Generated.cs | 1 + .../FileGenerate.B.Generated.cs | 1 + .../UnitOfAttribute.cs | 5 +- src/UnitGenerator/SourceGenerator.cs | 129 ++++++++-------- src/UnitGenerator/UnitGenerateOptions.cs | 2 +- 7 files changed, 104 insertions(+), 216 deletions(-) create mode 100644 sandbox/ConsoleApp/Operators.cs diff --git a/sandbox/ConsoleApp/Operators.cs b/sandbox/ConsoleApp/Operators.cs new file mode 100644 index 0000000..6ca8f81 --- /dev/null +++ b/sandbox/ConsoleApp/Operators.cs @@ -0,0 +1,37 @@ +using UnitGenerator; + +namespace ConsoleApp +{ + namespace ConsoleApp + { + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Addition)] + public readonly partial struct Add + { + } + + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Subtraction)] + public readonly partial struct Sub + { + } + + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Multiply)] + public readonly partial struct Mul + { + } + + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Division)] + public readonly partial struct Div + { + } + + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Increment)] + public readonly partial struct Inc + { + } + + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Decrement)] + public readonly partial struct Dec + { + } + } +} diff --git a/sandbox/ConsoleApp/Others.cs b/sandbox/ConsoleApp/Others.cs index de38d13..92eb317 100644 --- a/sandbox/ConsoleApp/Others.cs +++ b/sandbox/ConsoleApp/Others.cs @@ -1,6 +1,4 @@ using System; -using System.Globalization; -using System.Numerics; using UnitGenerator; namespace ConsoleApp @@ -37,147 +35,4 @@ private partial void Validate() _ = AsPrimitive(); } } - - public class N2 : IEquatable - { - public int X { get; } - - public bool Equals(N2? other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return X == other.X; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((N2)obj); - } - - public override int GetHashCode() => X; - } - - public class N : INumber - { - public int CompareTo(object? obj) => throw new NotImplementedException(); - - public int CompareTo(N? other) => throw new NotImplementedException(); - - public bool Equals(N? other) => throw new NotImplementedException(); - - public string ToString(string? format, IFormatProvider? formatProvider) => throw new NotImplementedException(); - - public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) => throw new NotImplementedException(); - - public static N Parse(string s, IFormatProvider? provider) => throw new NotImplementedException(); - - public static bool TryParse(string? s, IFormatProvider? provider, out N result) => throw new NotImplementedException(); - - public static N Parse(ReadOnlySpan s, IFormatProvider? provider) => throw new NotImplementedException(); - - public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out N result) => throw new NotImplementedException(); - - public static N operator +(N left, N right) => throw new NotImplementedException(); - - public static N AdditiveIdentity { get; } - public static bool operator ==(N? left, N? right) => throw new NotImplementedException(); - - public static bool operator !=(N? left, N? right) => throw new NotImplementedException(); - - public static bool operator >(N left, N right) => throw new NotImplementedException(); - - public static bool operator >=(N left, N right) => throw new NotImplementedException(); - - public static bool operator <(N left, N right) => throw new NotImplementedException(); - - public static bool operator <=(N left, N right) => throw new NotImplementedException(); - - public static N operator --(N value) => throw new NotImplementedException(); - - public static N operator /(N left, N right) => throw new NotImplementedException(); - - public static N operator ++(N value) => throw new NotImplementedException(); - - public static N operator %(N left, N right) => throw new NotImplementedException(); - - public static N MultiplicativeIdentity { get; } - public static N operator *(N left, N right) => throw new NotImplementedException(); - - public static N operator -(N left, N right) => throw new NotImplementedException(); - - public static N operator -(N value) => throw new NotImplementedException(); - - public static N operator +(N value) => throw new NotImplementedException(); - - public static N Abs(N value) => throw new NotImplementedException(); - - public static bool IsCanonical(N value) => throw new NotImplementedException(); - - public static bool IsComplexNumber(N value) => throw new NotImplementedException(); - - public static bool IsEvenInteger(N value) => throw new NotImplementedException(); - - public static bool IsFinite(N value) => throw new NotImplementedException(); - - public static bool IsImaginaryNumber(N value) => throw new NotImplementedException(); - - public static bool IsInfinity(N value) => throw new NotImplementedException(); - - public static bool IsInteger(N value) => throw new NotImplementedException(); - - public static bool IsNaN(N value) => throw new NotImplementedException(); - - public static bool IsNegative(N value) => throw new NotImplementedException(); - - public static bool IsNegativeInfinity(N value) => throw new NotImplementedException(); - - public static bool IsNormal(N value) => throw new NotImplementedException(); - - public static bool IsOddInteger(N value) => throw new NotImplementedException(); - - public static bool IsPositive(N value) => throw new NotImplementedException(); - - public static bool IsPositiveInfinity(N value) => throw new NotImplementedException(); - - public static bool IsRealNumber(N value) => throw new NotImplementedException(); - - public static bool IsSubnormal(N value) => throw new NotImplementedException(); - - public static bool IsZero(N value) => throw new NotImplementedException(); - - public static N MaxMagnitude(N x, N y) => throw new NotImplementedException(); - - public static N MaxMagnitudeNumber(N x, N y) => throw new NotImplementedException(); - - public static N MinMagnitude(N x, N y) => throw new NotImplementedException(); - - public static N MinMagnitudeNumber(N x, N y) => throw new NotImplementedException(); - - public static N Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => throw new NotImplementedException(); - - public static N Parse(string s, NumberStyles style, IFormatProvider? provider) => throw new NotImplementedException(); - - public static bool TryConvertFromChecked(TOther value, out N result) where TOther : INumberBase => throw new NotImplementedException(); - - public static bool TryConvertFromSaturating(TOther value, out N result) where TOther : INumberBase => throw new NotImplementedException(); - - public static bool TryConvertFromTruncating(TOther value, out N result) where TOther : INumberBase => throw new NotImplementedException(); - - public static bool TryConvertToChecked(N value, out TOther result) where TOther : INumberBase => throw new NotImplementedException(); - - public static bool TryConvertToSaturating(N value, out TOther result) where TOther : INumberBase => throw new NotImplementedException(); - - public static bool TryConvertToTruncating(N value, out TOther result) where TOther : INumberBase => throw new NotImplementedException(); - - public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out N result) => throw new NotImplementedException(); - - public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out N result) => throw new NotImplementedException(); - - public static N One { get; } - public static int Radix { get; } - public static N Zero { get; } - } } diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs index 4c88b2b..b6de7c2 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs @@ -74,6 +74,7 @@ public override string ToString() } // Default + private class ATypeConverter : System.ComponentModel.TypeConverter { private static readonly Type WrapperType = typeof(A); diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs index 07ba15a..6850d70 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs @@ -74,6 +74,7 @@ public override string ToString() } // Default + private class BTypeConverter : System.ComponentModel.TypeConverter { private static readonly Type WrapperType = typeof(B); diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs index d230a3e..b192535 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs @@ -13,7 +13,8 @@ internal class UnitOfAttribute : Attribute { public Type Type { get; } public UnitGenerateOptions Options { get; } - public string Format { get; } + public UnitGenerateArithmeticOperators ArithmeticOperators { get; set; } + public string Format { get; set; } public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None, string toStringFormat = null) { @@ -44,7 +45,7 @@ internal enum UnitGenerateOptions } [Flags] - internal enum UnitGenerateArithmeticOperator + internal enum UnitGenerateArithmeticOperators { Number = 0, Addition = 1, diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index b43ade5..29c77fb 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -36,6 +36,7 @@ public void Execute(GeneratorExecutionContext context) var prop = new UnitOfAttributeProperty(); if (attr.ArgumentList is null) goto ADD; + for (int i = 0; i < attr.ArgumentList.Arguments.Count; i++) { var arg = attr.ArgumentList.Arguments[i]; @@ -60,10 +61,20 @@ public void Execute(GeneratorExecutionContext context) var parsed = Enum.ToObject(typeof(UnitGenerateOptions), model.GetConstantValue(expr).Value); prop.Options = (UnitGenerateOptions)parsed; } - else if (i == 2) // string toStringFormat + else { - var format = model.GetConstantValue(expr).Value?.ToString(); - prop.ToStringFormat = format; + var argName = arg.NameEquals?.Name.ToString(); + switch (argName) + { + case "ArithmeticOperators": + var parsed = Enum.ToObject(typeof(UnitGenerateArithmeticOperators), model.GetConstantValue(expr).Value); + prop.ArithmeticOperators = (UnitGenerateArithmeticOperators)parsed; + break; + case "Format": + var format = model.GetConstantValue(expr).Value?.ToString(); + prop.ToStringFormat = format; + break; + } } } @@ -122,7 +133,8 @@ internal class UnitOfAttribute : Attribute { public Type Type { get; } public UnitGenerateOptions Options { get; } - public string Format { get; } + public UnitGenerateArithmeticOperators ArithmeticOperators { get; set; } + public string Format { get; set; } public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None, string toStringFormat = null) { @@ -153,7 +165,7 @@ internal enum UnitGenerateOptions } [Flags] - internal enum UnitGenerateArithmeticOperator + internal enum UnitGenerateArithmeticOperators { Number = 0, Addition = 1, @@ -194,12 +206,6 @@ internal static class AsNumber where T : INumber public static T MaxMagnitudeNumber(T x, T y) => T.MaxMagnitudeNumber(x, y); public static T MinMagnitude(T x, T y) => T.MinMagnitude(x, y); public static T MinMagnitudeNumber(T x, T y) => T.MinMagnitudeNumber(x, y); - public static bool TryConvertFromChecked(TOther value, out T result) => T.TryConvertFromChecked(value, out result); - public static bool TryConvertFromSaturating(TOther value, out T result) => T.TryConvertFromSaturating(value, out result); - public static bool TryConvertFromTruncating(TOther value, out T result) => T.TryConvertFromTruncating(value, out result); - public static bool TryConvertToChecked(T value, out TOther result) => T.TryConvertToChecked(value, out result); - public static bool TryConvertToSaturating(T value, out TOther result) => T.TryConvertToSaturating(value, out result); - public static bool TryConvertToTruncating(T value, out TOther result) => T.TryConvertToTruncating(value, out result); } #endif } @@ -307,39 +313,39 @@ readonly partial struct {{unitTypeName}} if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) { sb.AppendLine("#if NET7_0_OR_GREATER"); - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Addition)) { sb.AppendLine($$""" , IAdditionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Subtraction)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) { sb.AppendLine($$""" , ISubtractionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition | - UnitGenerateArithmeticOperator.Subtraction)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Addition) || + prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) { sb.AppendLine($$""" , IAdditiveIdentity<{{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Multiply)) { sb.AppendLine($$""" , IMultiplyOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Division)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Division)) { sb.AppendLine($$""" , IDivisionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply | - UnitGenerateArithmeticOperator.Division)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Multiply) || + prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Division)) { sb.AppendLine($$""" , IMultiplicativeIdentity<{{unitTypeName}}, {{unitTypeName}}> @@ -347,13 +353,13 @@ readonly partial struct {{unitTypeName}} , IUnaryNegationOperators<{{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Increment)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Increment)) { sb.AppendLine($$""" , IIncrementOperators<{{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Decrement)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Decrement)) { sb.AppendLine($$""" , IDecrementOperators<{{unitTypeName}}> @@ -614,8 +620,8 @@ public static bool TryParse(string s, out {{unitTypeName}} result) // UnitGenerateOptions.ArithmeticOperator """); - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition | - UnitGenerateArithmeticOperator.Subtraction)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Addition) || + prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) { sb.AppendLine($$""" #if NET7_0_OR_GREATER @@ -623,7 +629,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) #endif """); - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Addition)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Addition)) { sb.AppendLine($$""" public static {{unitTypeName}} operator +({{unitTypeName}} x, {{unitTypeName}} y) @@ -636,7 +642,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Subtraction)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) { sb.AppendLine($$""" public static {{unitTypeName}} operator -({{unitTypeName}} x, {{unitTypeName}} y) @@ -651,8 +657,8 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } // End Addition, Subtraction - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply | - UnitGenerateArithmeticOperator.Division)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Multiply) || + prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Division)) { sb.AppendLine($$""" #if NET7_0_OR_GREATER @@ -662,7 +668,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) public static {{unitTypeName}} operator -({{unitTypeName}} value) => new(({{innerTypeName}})(-value.value)); """); - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Multiply)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Multiply)) { sb.AppendLine($$""" public static {{unitTypeName}} operator *({{unitTypeName}} x, {{unitTypeName}} y) @@ -675,7 +681,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Division)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Division)) { sb.AppendLine($$""" @@ -691,7 +697,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } // End Multiply, Division - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Increment)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Increment)) { sb.AppendLine($$""" public static {{unitTypeName}} operator ++({{unitTypeName}} x) @@ -704,7 +710,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperator.Decrement)) + if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Decrement)) { sb.AppendLine($$""" public static {{unitTypeName}} operator --({{unitTypeName}} x) @@ -721,7 +727,11 @@ public static bool TryParse(string s, out {{unitTypeName}} result) if (prop.HasFlag(UnitGenerateOptions.ValueArithmeticOperator)) { - if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperator.Addition)) + sb.AppendLine(""" + // UnitGenerateOptions.ValueArithmeticOperator + +"""); + if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperators.Addition)) { sb.AppendLine($$""" public static {{unitTypeName}} operator +({{unitTypeName}} x, {{innerTypeName}} y) @@ -734,7 +744,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperator.Subtraction)) + if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) { sb.AppendLine($$""" public static {{unitTypeName}} operator -({{unitTypeName}} x, {{innerTypeName}} y) @@ -747,7 +757,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperator.Multiply)) + if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperators.Multiply)) { sb.AppendLine($$""" public static {{unitTypeName}} operator *({{unitTypeName}} x, {{innerTypeName}} y) @@ -760,7 +770,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperator.Division)) + if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperators.Division)) { sb.AppendLine($$""" @@ -906,52 +916,34 @@ public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out public static bool TryConvertFromChecked(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - if (global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertFromChecked(value, out var innerResult)) - { - result = new {{unitTypeName}}(innerResult); - return true; - } - result = default; - return false; + throw new NotSupportedException(); } public static bool TryConvertFromSaturating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - if (global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertFromSaturating(value, out var innerResult)) - { - result = new {{unitTypeName}}(innerResult); - return true; - } - result = default; - return false; + throw new NotSupportedException(); } public static bool TryConvertFromTruncating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - if (global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertFromTruncating(value, out var innerResult)) - { - result = new {{unitTypeName}}(innerResult); - return true; - } - result = default; - return false; + throw new NotSupportedException(); } public static bool TryConvertToChecked({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertToChecked(value.value, out result); + throw new NotSupportedException(); } public static bool TryConvertToSaturating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertToSaturating(value.value, out result); + throw new NotSupportedException(); } public static bool TryConvertToTruncating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - return global::UnitGenerator.AsNumber<{{innerTypeName}}>.TryConvertToTruncating(value.value, out result); + throw new NotSupportedException(); } - + public static {{unitTypeName}} Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); public static {{unitTypeName}} Parse(string s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); @@ -1175,6 +1167,7 @@ public class {{unitTypeName}}ValueConverter : Microsoft.EntityFrameworkCore.Stor sb.AppendLine($$""" // Default + private class {{unitTypeName}}TypeConverter : System.ComponentModel.TypeConverter { private static readonly Type WrapperType = typeof({{unitTypeName}}); @@ -1250,7 +1243,7 @@ struct UnitOfAttributeProperty { public ITypeSymbol Type { get; set; } public UnitGenerateOptions Options { get; set; } - public UnitGenerateArithmeticOperator ArithmeticOperator { get; set; } + public UnitGenerateArithmeticOperators ArithmeticOperators { get; set; } public string? ToStringFormat { get; set; } public string TypeName => Type.ToString(); @@ -1262,20 +1255,20 @@ struct UnitOfAttributeProperty public bool HasFlag(UnitGenerateOptions options) => Options.HasFlag(options); public bool IsNumber() => HasFlag(UnitGenerateOptions.ArithmeticOperator) && - ArithmeticOperator == UnitGenerateArithmeticOperator.Number; + ArithmeticOperators == UnitGenerateArithmeticOperators.Number; - public bool HasArithmeticOperator(UnitGenerateArithmeticOperator op) + public bool HasArithmeticOperator(UnitGenerateArithmeticOperators op) { return HasFlag(UnitGenerateOptions.ArithmeticOperator) && - (ArithmeticOperator == UnitGenerateArithmeticOperator.Number || - ArithmeticOperator.HasFlag(op)); + (ArithmeticOperators == UnitGenerateArithmeticOperators.Number || + ArithmeticOperators.HasFlag(op)); } - public bool HasValueArithmeticOperator(UnitGenerateArithmeticOperator op) + public bool HasValueArithmeticOperator(UnitGenerateArithmeticOperators op) { return HasFlag(UnitGenerateOptions.ValueArithmeticOperator) && - (ArithmeticOperator == UnitGenerateArithmeticOperator.Number || - ArithmeticOperator.HasFlag(op)); + (ArithmeticOperators == UnitGenerateArithmeticOperators.Number || + ArithmeticOperators.HasFlag(op)); } public DbType GetDbType() diff --git a/src/UnitGenerator/UnitGenerateOptions.cs b/src/UnitGenerator/UnitGenerateOptions.cs index 7573fe3..df43b98 100644 --- a/src/UnitGenerator/UnitGenerateOptions.cs +++ b/src/UnitGenerator/UnitGenerateOptions.cs @@ -24,7 +24,7 @@ internal enum UnitGenerateOptions } [Flags] - internal enum UnitGenerateArithmeticOperator + internal enum UnitGenerateArithmeticOperators { Number = 0, Addition = 1, From 7015c0fe08d8913ca97f3e988edde607bb04d950 Mon Sep 17 00:00:00 2001 From: hadashiA Date: Thu, 17 Aug 2023 00:27:49 +0900 Subject: [PATCH 07/12] Fix some api names --- src/UnitGenerator/SourceGenerator.cs | 77 ++++++++++++------------ src/UnitGenerator/UnitGenerateOptions.cs | 2 +- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index 29c77fb..dc3ec7d 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -67,10 +67,10 @@ public void Execute(GeneratorExecutionContext context) switch (argName) { case "ArithmeticOperators": - var parsed = Enum.ToObject(typeof(UnitGenerateArithmeticOperators), model.GetConstantValue(expr).Value); - prop.ArithmeticOperators = (UnitGenerateArithmeticOperators)parsed; + var parsed = Enum.ToObject(typeof(UnitArithmeticOperators), model.GetConstantValue(expr).Value); + prop.ArithmeticOperators = (UnitArithmeticOperators)parsed; break; - case "Format": + case "ToStringFormat": var format = model.GetConstantValue(expr).Value?.ToString(); prop.ToStringFormat = format; break; @@ -133,14 +133,13 @@ internal class UnitOfAttribute : Attribute { public Type Type { get; } public UnitGenerateOptions Options { get; } - public UnitGenerateArithmeticOperators ArithmeticOperators { get; set; } - public string Format { get; set; } + public UnitArithmeticOperators ArithmeticOperators { get; set; } + public string ToStringFormat { get; set; } - public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None, string toStringFormat = null) + public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None) { this.Type = type; this.Options = options; - this.Format = toStringFormat; } } @@ -165,7 +164,7 @@ internal enum UnitGenerateOptions } [Flags] - internal enum UnitGenerateArithmeticOperators + internal enum UnitArithmeticOperators { Number = 0, Addition = 1, @@ -313,39 +312,39 @@ readonly partial struct {{unitTypeName}} if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) { sb.AppendLine("#if NET7_0_OR_GREATER"); - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Addition)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition)) { sb.AppendLine($$""" , IAdditionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) { sb.AppendLine($$""" , ISubtractionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Addition) || - prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition) || + prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) { sb.AppendLine($$""" , IAdditiveIdentity<{{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Multiply)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply)) { sb.AppendLine($$""" , IMultiplyOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Division)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) { sb.AppendLine($$""" , IDivisionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Multiply) || - prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Division)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply) || + prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) { sb.AppendLine($$""" , IMultiplicativeIdentity<{{unitTypeName}}, {{unitTypeName}}> @@ -353,13 +352,13 @@ readonly partial struct {{unitTypeName}} , IUnaryNegationOperators<{{unitTypeName}}, {{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Increment)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Increment)) { sb.AppendLine($$""" , IIncrementOperators<{{unitTypeName}}> """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Decrement)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Decrement)) { sb.AppendLine($$""" , IDecrementOperators<{{unitTypeName}}> @@ -620,8 +619,8 @@ public static bool TryParse(string s, out {{unitTypeName}} result) // UnitGenerateOptions.ArithmeticOperator """); - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Addition) || - prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition) || + prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) { sb.AppendLine($$""" #if NET7_0_OR_GREATER @@ -629,7 +628,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) #endif """); - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Addition)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition)) { sb.AppendLine($$""" public static {{unitTypeName}} operator +({{unitTypeName}} x, {{unitTypeName}} y) @@ -642,7 +641,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) { sb.AppendLine($$""" public static {{unitTypeName}} operator -({{unitTypeName}} x, {{unitTypeName}} y) @@ -657,8 +656,8 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } // End Addition, Subtraction - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Multiply) || - prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Division)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply) || + prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) { sb.AppendLine($$""" #if NET7_0_OR_GREATER @@ -668,7 +667,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) public static {{unitTypeName}} operator -({{unitTypeName}} value) => new(({{innerTypeName}})(-value.value)); """); - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Multiply)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply)) { sb.AppendLine($$""" public static {{unitTypeName}} operator *({{unitTypeName}} x, {{unitTypeName}} y) @@ -681,7 +680,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Division)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) { sb.AppendLine($$""" @@ -697,7 +696,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } // End Multiply, Division - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Increment)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Increment)) { sb.AppendLine($$""" public static {{unitTypeName}} operator ++({{unitTypeName}} x) @@ -710,7 +709,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasArithmeticOperator(UnitGenerateArithmeticOperators.Decrement)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Decrement)) { sb.AppendLine($$""" public static {{unitTypeName}} operator --({{unitTypeName}} x) @@ -731,7 +730,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) // UnitGenerateOptions.ValueArithmeticOperator """); - if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperators.Addition)) + if (prop.HasValueArithmeticOperator(UnitArithmeticOperators.Addition)) { sb.AppendLine($$""" public static {{unitTypeName}} operator +({{unitTypeName}} x, {{innerTypeName}} y) @@ -744,7 +743,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperators.Subtraction)) + if (prop.HasValueArithmeticOperator(UnitArithmeticOperators.Subtraction)) { sb.AppendLine($$""" public static {{unitTypeName}} operator -({{unitTypeName}} x, {{innerTypeName}} y) @@ -757,7 +756,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperators.Multiply)) + if (prop.HasValueArithmeticOperator(UnitArithmeticOperators.Multiply)) { sb.AppendLine($$""" public static {{unitTypeName}} operator *({{unitTypeName}} x, {{innerTypeName}} y) @@ -770,7 +769,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) """); } - if (prop.HasValueArithmeticOperator(UnitGenerateArithmeticOperators.Division)) + if (prop.HasValueArithmeticOperator(UnitArithmeticOperators.Division)) { sb.AppendLine($$""" @@ -1243,7 +1242,7 @@ struct UnitOfAttributeProperty { public ITypeSymbol Type { get; set; } public UnitGenerateOptions Options { get; set; } - public UnitGenerateArithmeticOperators ArithmeticOperators { get; set; } + public UnitArithmeticOperators ArithmeticOperators { get; set; } public string? ToStringFormat { get; set; } public string TypeName => Type.ToString(); @@ -1255,19 +1254,19 @@ struct UnitOfAttributeProperty public bool HasFlag(UnitGenerateOptions options) => Options.HasFlag(options); public bool IsNumber() => HasFlag(UnitGenerateOptions.ArithmeticOperator) && - ArithmeticOperators == UnitGenerateArithmeticOperators.Number; + ArithmeticOperators == UnitArithmeticOperators.Number; - public bool HasArithmeticOperator(UnitGenerateArithmeticOperators op) + public bool HasArithmeticOperator(UnitArithmeticOperators op) { return HasFlag(UnitGenerateOptions.ArithmeticOperator) && - (ArithmeticOperators == UnitGenerateArithmeticOperators.Number || + (ArithmeticOperators == UnitArithmeticOperators.Number || ArithmeticOperators.HasFlag(op)); } - public bool HasValueArithmeticOperator(UnitGenerateArithmeticOperators op) + public bool HasValueArithmeticOperator(UnitArithmeticOperators op) { return HasFlag(UnitGenerateOptions.ValueArithmeticOperator) && - (ArithmeticOperators == UnitGenerateArithmeticOperators.Number || + (ArithmeticOperators == UnitArithmeticOperators.Number || ArithmeticOperators.HasFlag(op)); } @@ -1338,4 +1337,4 @@ public void OnVisitSyntaxNode(SyntaxNode syntaxNode) } } } -} \ No newline at end of file +} diff --git a/src/UnitGenerator/UnitGenerateOptions.cs b/src/UnitGenerator/UnitGenerateOptions.cs index df43b98..c166695 100644 --- a/src/UnitGenerator/UnitGenerateOptions.cs +++ b/src/UnitGenerator/UnitGenerateOptions.cs @@ -24,7 +24,7 @@ internal enum UnitGenerateOptions } [Flags] - internal enum UnitGenerateArithmeticOperators + internal enum UnitArithmeticOperators { Number = 0, Addition = 1, From 8c2cc1e6ccadf3489c65ee927ff4710b3b33ef28 Mon Sep 17 00:00:00 2001 From: hadashiA Date: Thu, 17 Aug 2023 00:27:59 +0900 Subject: [PATCH 08/12] Update README --- README.md | 69 ++++++++++++++----- sandbox/ConsoleApp/Operators.cs | 12 ++-- .../UnitOfAttribute.cs | 9 ++- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index d06760e..36d9b73 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,14 @@ public readonly partial struct Hp { } // -- generates [System.ComponentModel.TypeConverter(typeof(HpTypeConverter))] -public readonly partial struct Hp : IEquatable , IComparable +public readonly partial struct Hp +#if NET7_0_OR_GREATER + : INumber +#else + : IEquatable + , IComparable + , IComparable +#endif { readonly int value; @@ -81,25 +88,38 @@ public readonly partial struct Hp : IEquatable , IComparable private class HpTypeConverter : System.ComponentModel.TypeConverter { /* snip... */ } // UnitGenerateOptions.ArithmeticOperator - public static Hp operator +(in Hp x, in Hp y) => new Hp(checked((int)(x.value + y.value))); - public static Hp operator -(in Hp x, in Hp y) => new Hp(checked((int)(x.value - y.value))); - public static Hp operator *(in Hp x, in Hp y) => new Hp(checked((int)(x.value * y.value))); - public static Hp operator /(in Hp x, in Hp y) => new Hp(checked((int)(x.value / y.value))); + public static Hp operator +(Hp x, Hp y) => new Hp(checked((int)(x.value + y.value))); + public static Hp operator -(Hp x, Hp y) => new Hp(checked((int)(x.value - y.value))); + public static Hp operator *(Hp x, Hp y) => new Hp(checked((int)(x.value * y.value))); + public static Hp operator /(Hp x, Hp y) => new Hp(checked((int)(x.value / y.value))); + public static Hp operator ++(Hp x) => new Hp(checked((int)(x.value + 1))); + public static Hp operator --(Hp x) => new Hp(checked((int)(x.value - 1))); + public static Hp operator +(A value) => new((int)(+value.value)); + public static Hp operator -(A value) => new((int)(-value.value)); + + // In addition, .ArithmeticOperator option also generates all members of `System.Numerics.INumber` by default. +#if NET7_0_OR_GREATER + public static Hp AdditiveIdentity => new(global::UnitGenerator.AsNumber.AdditiveIdentity); + public static Hp MultiplicativeIdentity => new(global::UnitGenerator.AsNumber.MultiplicativeIdentity); + public static HP One => new(global::UnitGenerator.AsNumber.One); + public static int Radix => global::UnitGenerator.AsNumber.Radix; + public static Hp Zero => new(global::UnitGenerator.AsNumber.Zero); + public static Hp Abs(Hp value) => new(global::UnitGenerator.AsNumber.Abs(value.value)); + // etc...... +#endif // UnitGenerateOptions.ValueArithmeticOperator - public static Hp operator ++(in Hp x) => new Hp(checked((int)(x.value + 1))); - public static Hp operator --(in Hp x) => new Hp(checked((int)(x.value - 1))); - public static Hp operator +(in Hp x, in int y) => new Hp(checked((int)(x.value + y))); - public static Hp operator -(in Hp x, in int y) => new Hp(checked((int)(x.value - y))); - public static Hp operator *(in Hp x, in int y) => new Hp(checked((int)(x.value * y))); - public static Hp operator /(in Hp x, in int y) => new Hp(checked((int)(x.value / y))); + public static Hp operator +(Hp x, in int y) => new Hp(checked((int)(x.value + y))); + public static Hp operator -(Hp x, in int y) => new Hp(checked((int)(x.value - y))); + public static Hp operator *(Hp x, in int y) => new Hp(checked((int)(x.value * y))); + public static Hp operator /(Hp x, in int y) => new Hp(checked((int)(x.value / y))); // UnitGenerateOptions.Comparable public int CompareTo(Hp other) => value.CompareTo(other.value); - public static bool operator >(in Hp x, in Hp y) => x.value > y.value; - public static bool operator <(in Hp x, in Hp y) => x.value < y.value; - public static bool operator >=(in Hp x, in Hp y) => x.value >= y.value; - public static bool operator <=(in Hp x, in Hp y) => x.value <= y.value; + public static bool operator >(Hp x, Hp y) => x.value > y.value; + public static bool operator <(Hp x, Hp y) => x.value < y.value; + public static bool operator >=(Hp x, Hp y) => x.value >= y.value; + public static bool operator <=(Hp x, Hp y) => x.value <= y.value; // UnitGenerateOptions.MinMaxMethod public static Hp Min(Hp x, Hp y) => new Hp(Math.Min(x.value, y.value)); @@ -193,7 +213,12 @@ namespace UnitGenerator [AttributeUsage(AttributeTargets.Struct, AllowMultiple = false)] internal class UnitOfAttribute : Attribute { - public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None, string toStringFormat = null) + public Type Type { get; } + public UnitGenerateOptions Options { get; } + public UnitArithmeticOperators ArithmeticOperators { get; set; } + public string ToStringFormat { get; set; } + + public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None) } } ``` @@ -241,7 +266,9 @@ public static GroupId NewGroupId(); Second parameter `UnitGenerateOptions options` can configure which method to implement, default is `None`. -Third parameter `strign toStringFormat` can configure `ToString` format. Default is null and output as $`{0}`. +Optional named parameter: `ArithmeticOperators` can configure which generates operators specifically. (This can be used if UnitGenerateOptions.ArithmeticOperator is specified.) + +Optional named parameter: `ToStringFormat` can configure `ToString` format. Default is null and output as $`{0}`. ## UnitGenerateOptions @@ -269,7 +296,13 @@ internal enum UnitGenerateOptions You can use this with `[UnitOf]`. ```csharp -[UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.MinMaxMethod)] +[UnitOf( + typeof(int), + UnitGenerateOptions.ArithmeticOperator | + UnitGenerateOptions.ValueArithmeticOperator | + UnitGenerateOptions.Comparable | + UnitGenerateOptions.MinMaxMethod, + ArithemticOperators = UnitGenerate)] public readonly partial struct Strength { } [UnitOf(typeof(DateTime), UnitGenerateOptions.Validate | UnitGenerateOptions.ParseMethod | UnitGenerateOptions.Comparable)] diff --git a/sandbox/ConsoleApp/Operators.cs b/sandbox/ConsoleApp/Operators.cs index 6ca8f81..ff31ef6 100644 --- a/sandbox/ConsoleApp/Operators.cs +++ b/sandbox/ConsoleApp/Operators.cs @@ -4,32 +4,32 @@ namespace ConsoleApp { namespace ConsoleApp { - [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Addition)] + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Addition)] public readonly partial struct Add { } - [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Subtraction)] + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Subtraction)] public readonly partial struct Sub { } - [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Multiply)] + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Multiply)] public readonly partial struct Mul { } - [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Division)] + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Division)] public readonly partial struct Div { } - [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Increment)] + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Increment)] public readonly partial struct Inc { } - [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitGenerateArithmeticOperators.Decrement)] + [UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Decrement)] public readonly partial struct Dec { } diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs index b192535..bbb057c 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs @@ -13,14 +13,13 @@ internal class UnitOfAttribute : Attribute { public Type Type { get; } public UnitGenerateOptions Options { get; } - public UnitGenerateArithmeticOperators ArithmeticOperators { get; set; } - public string Format { get; set; } + public UnitArithmeticOperators ArithmeticOperators { get; set; } + public string ToStringFormat { get; set; } - public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None, string toStringFormat = null) + public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None) { this.Type = type; this.Options = options; - this.Format = toStringFormat; } } @@ -45,7 +44,7 @@ internal enum UnitGenerateOptions } [Flags] - internal enum UnitGenerateArithmeticOperators + internal enum UnitArithmeticOperators { Number = 0, Addition = 1, From 039b25a5b4863b9ca14a42ce0b045ae46433104d Mon Sep 17 00:00:00 2001 From: hadashiA Date: Thu, 17 Aug 2023 10:10:46 +0900 Subject: [PATCH 09/12] README --- README.md | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 36d9b73..c38bedf 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ public readonly partial struct Hp public static Hp operator +(A value) => new((int)(+value.value)); public static Hp operator -(A value) => new((int)(-value.value)); - // In addition, .ArithmeticOperator option also generates all members of `System.Numerics.INumber` by default. + // The .ArithmeticOperator option also generates all members of `System.Numerics.INumber` by default. #if NET7_0_OR_GREATER public static Hp AdditiveIdentity => new(global::UnitGenerator.AsNumber.AdditiveIdentity); public static Hp MultiplicativeIdentity => new(global::UnitGenerator.AsNumber.MultiplicativeIdentity); @@ -218,7 +218,7 @@ namespace UnitGenerator public UnitArithmeticOperators ArithmeticOperators { get; set; } public string ToStringFormat { get; set; } - public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None) + public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None) { ... } } } ``` @@ -266,7 +266,7 @@ public static GroupId NewGroupId(); Second parameter `UnitGenerateOptions options` can configure which method to implement, default is `None`. -Optional named parameter: `ArithmeticOperators` can configure which generates operators specifically. (This can be used if UnitGenerateOptions.ArithmeticOperator is specified.) +Optional named parameter: `ArithmeticOperators` can configure which generates operators specifically. Default is `Number`. (This can be used if UnitGenerateOptions.ArithmeticOperator is specified.) Optional named parameter: `ToStringFormat` can configure `ToString` format. Default is null and output as $`{0}`. @@ -296,13 +296,7 @@ internal enum UnitGenerateOptions You can use this with `[UnitOf]`. ```csharp -[UnitOf( - typeof(int), - UnitGenerateOptions.ArithmeticOperator | - UnitGenerateOptions.ValueArithmeticOperator | - UnitGenerateOptions.Comparable | - UnitGenerateOptions.MinMaxMethod, - ArithemticOperators = UnitGenerate)] +[UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator | UnitGenerateOptions.Comparable | UnitGenerateOptions.MinMaxMethod)] public readonly partial struct Strength { } [UnitOf(typeof(DateTime), UnitGenerateOptions.Validate | UnitGenerateOptions.ParseMethod | UnitGenerateOptions.Comparable)] @@ -357,13 +351,37 @@ public static T operator +(in T x, in T y) => new T(checked((U)(x.value + y.valu public static T operator -(in T x, in T y) => new T(checked((U)(x.value - y.value))); public static T operator *(in T x, in T y) => new T(checked((U)(x.value * y.value))); public static T operator /(in T x, in T y) => new T(checked((U)(x.value / y.value))); +public static T operator +(T value) => new((U)(+value.value)); +public static T operator -(T value) => new((U)(-value.value)); +public static T operator ++(T x) => new T(checked((U)(x.value + 1))); +public static T operator --(T x) => new T(checked((U)(x.value - 1))); ``` +In addition, all members conforming to [System.Numerics.INumber](https://learn.microsoft.com/ja-jp/dotnet/api/system.numerics.inumber-1) are generated. + +If you want to suppress this and generate only certain operators, you can use the the `ArithmeticOperatros` option of `[UnitOf]` attribute as follows: + +```csharp +[UnitOf( + typeof(int), + UnitGenerateOptions.ArithmeticOperator, + ArithmeticOperators = UnitArithmeticOperators.Addition | UnitArithmeticOperators.Subtraction)] +public readonly partial struct Hp { } +``` + +| Value | Generates | +|-------------------------------------|----------------------------------------------------------------------------------------| +| UnitArithmeticOperators.Addition | `T operator +(T, T)`, `T AdditiveIdentity` | +| UnitArithmeticOperators.Subtraction | `T operator -(T, T)`, `T AdditiveIdentity` | +| UnitArithmeticOperators.Multiply | `T operator *(T, T)`, `T operator +(T)`, `T operator-(T)`, `T MultiplicativeIdentity` | +| UnitArithmeticOperators.Division | `T operator /(T, T)`, `T operator +(T)`, `T operator-(T)`, `T MultiplicativeIdentity` | +| UnitArithmeticOperators.Increment | `T operator ++(T)` | +| UnitArithmeticOperators.Decrement | `T operator --(T)` | + + ### ValueArithmeticOperator ```csharp -public static T operator ++(in T x) => new T(checked((U)(x.value + 1))); -public static T operator --(in T x) => new T(checked((U)(x.value - 1))); public static T operator +(in T x, in U y) => new T(checked((U)(x.value + y))); public static T operator -(in T x, in U y) => new T(checked((U)(x.value - y))); public static T operator *(in T x, in U y) => new T(checked((U)(x.value * y))); From 88633645115207ed30e30f872e33f4d73a56e792 Mon Sep 17 00:00:00 2001 From: hadashiA Date: Thu, 17 Aug 2023 10:56:20 +0900 Subject: [PATCH 10/12] Fix TryConvert impls, NotSupported -> return false --- src/UnitGenerator/SourceGenerator.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index dc3ec7d..462bd51 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -915,32 +915,39 @@ public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out public static bool TryConvertFromChecked(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - throw new NotSupportedException(); + result = default; + return false; } public static bool TryConvertFromSaturating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - throw new NotSupportedException(); + result = default; + return false; } public static bool TryConvertFromTruncating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase { - throw new NotSupportedException(); + result = default; + return false; + } public static bool TryConvertToChecked({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - throw new NotSupportedException(); + result = default; + return false; } public static bool TryConvertToSaturating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - throw new NotSupportedException(); + result = default; + return false; } public static bool TryConvertToTruncating({{unitTypeName}} value, out TOther result) where TOther : INumberBase { - throw new NotSupportedException(); + result = default; + return false; } public static {{unitTypeName}} Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); From 2b837ca82fe5392bb58e98c3b9dcee4c78d478d7 Mon Sep 17 00:00:00 2001 From: hadashiA Date: Thu, 17 Aug 2023 17:08:21 +0900 Subject: [PATCH 11/12] Remove INumber<> implementations --- sandbox/FileGenerate/SimplePrimitive.cs | 12 +- .../FileGenerate.A.Generated.cs | 11 +- .../FileGenerate.B.Generated.cs | 11 +- .../FileGenerate.C.Generated.cs | 272 ++++++++++++++ .../UnitOfAttribute.cs | 39 +- src/UnitGenerator/SourceGenerator.cs | 341 +++--------------- src/UnitGenerator/UnitGenerateOptions.cs | 2 +- 7 files changed, 349 insertions(+), 339 deletions(-) create mode 100644 sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.C.Generated.cs diff --git a/sandbox/FileGenerate/SimplePrimitive.cs b/sandbox/FileGenerate/SimplePrimitive.cs index 6e521fa..705e25c 100644 --- a/sandbox/FileGenerate/SimplePrimitive.cs +++ b/sandbox/FileGenerate/SimplePrimitive.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnitGenerator; +using UnitGenerator; namespace FileGenerate { @@ -16,4 +11,9 @@ public readonly partial struct A public readonly partial struct B { } + + [UnitOf(typeof(int), UnitGenerateOptions.Comparable | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator)] + public readonly partial struct C + { + } } diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs index b6de7c2..4074261 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.A.Generated.cs @@ -2,16 +2,19 @@ // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // #pragma warning disable CS8669 -#nullable enable using System; +using System.Globalization; +#if NET7_0_OR_GREATER +using System.Numerics; +#endif namespace FileGenerate { [System.ComponentModel.TypeConverter(typeof(ATypeConverter))] - readonly partial struct A - : IEquatable<{A> + readonly partial struct A + : IEquatable #if NET7_0_OR_GREATER , IEqualityOperators -#endif +#endif { readonly int value; diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs index 6850d70..75fc7bf 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.B.Generated.cs @@ -2,16 +2,19 @@ // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // #pragma warning disable CS8669 -#nullable enable using System; +using System.Globalization; +#if NET7_0_OR_GREATER +using System.Numerics; +#endif namespace FileGenerate { [System.ComponentModel.TypeConverter(typeof(BTypeConverter))] - readonly partial struct B - : IEquatable<{B> + readonly partial struct B + : IEquatable #if NET7_0_OR_GREATER , IEqualityOperators -#endif +#endif { readonly string value; diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.C.Generated.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.C.Generated.cs new file mode 100644 index 0000000..09fe8e8 --- /dev/null +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/FileGenerate.C.Generated.cs @@ -0,0 +1,272 @@ +// +// THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. +// +#pragma warning disable CS8669 +using System; +using System.Globalization; +#if NET7_0_OR_GREATER +using System.Numerics; +#endif +namespace FileGenerate +{ + [System.ComponentModel.TypeConverter(typeof(CTypeConverter))] + readonly partial struct C + : IEquatable +#if NET7_0_OR_GREATER + , IEqualityOperators +#endif + , IComparable +#if NET7_0_OR_GREATER + , IComparisonOperators +#endif +#if NET7_0_OR_GREATER + , IAdditionOperators + , ISubtractionOperators + , IMultiplyOperators + , IDivisionOperators + , IUnaryPlusOperators + , IUnaryNegationOperators + , IIncrementOperators + , IDecrementOperators +#endif + { + readonly int value; + + public int AsPrimitive() => value; + + public C(int value) + { + this.value = value; + } + + public static explicit operator int(C value) + { + return value.value; + } + + public static explicit operator C(int value) + { + return new C(value); + } + + public bool Equals(C other) + { + return value.Equals(other.value); + } + + public override bool Equals(object obj) + { + if (obj == null) return false; + var t = obj.GetType(); + if (t == typeof(C)) + { + return Equals((C)obj); + } + if (t == typeof(int)) + { + return value.Equals((int)obj); + } + + return value.Equals(obj); + } + + public static bool operator ==(C x, C y) + { + return x.value.Equals(y.value); + } + + public static bool operator !=(C x, C y) + { + return !x.value.Equals(y.value); + } + + public override int GetHashCode() + { + return value.GetHashCode(); + } + + public override string ToString() + { + return value.ToString(); + } + + // UnitGenerateOptions.ArithmeticOperator + + public static C operator +(C x, C y) + { + checked + { + return new C((int)(x.value + y.value)); + } + } + + public static C operator -(C x, C y) + { + checked + { + return new C((int)(x.value - y.value)); + } + } + + public static C operator +(C value) => new((int)(+value.value)); + public static C operator -(C value) => new((int)(-value.value)); + + public static C operator *(C x, C y) + { + checked + { + return new C((int)(x.value * y.value)); + } + } + + + public static C operator /(C x, C y) + { + checked + { + return new C((int)(x.value / y.value)); + } + } + + public static C operator ++(C x) + { + checked + { + return new C((int)((int)(x.value + 1))); + } + } + + public static C operator --(C x) + { + checked + { + return new C((int)((int)(x.value - 1))); + } + } + + // UnitGenerateOptions.ValueArithmeticOperator + + public static C operator +(C x, int y) + { + checked + { + return new C((int)(x.value + y)); + } + } + + public static C operator -(C x, int y) + { + checked + { + return new C((int)(x.value - y)); + } + } + + public static C operator *(C x, int y) + { + checked + { + return new C((int)(x.value * y)); + } + } + + + public static C operator /(C x, int y) + { + checked + { + return new C((int)(x.value / y)); + } + } + + // UnitGenerateOptions.Comparable + + public int CompareTo(C other) + { + return value.CompareTo(other.value); + } + public static bool operator >(C x, C y) + { + return x.value > y.value; + } + + public static bool operator <(C x, C y) + { + return x.value < y.value; + } + + public static bool operator >=(C x, C y) + { + return x.value >= y.value; + } + + public static bool operator <=(C x, C y) + { + return x.value <= y.value; + } + + // Default + + private class CTypeConverter : System.ComponentModel.TypeConverter + { + private static readonly Type WrapperType = typeof(C); + private static readonly Type ValueType = typeof(int); + + public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType) + { + if (sourceType == WrapperType || sourceType == ValueType) + { + return true; + } + + return base.CanConvertFrom(context, sourceType); + } + + public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, Type destinationType) + { + if (destinationType == WrapperType || destinationType == ValueType) + { + return true; + } + + return base.CanConvertTo(context, destinationType); + } + + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) + { + if (value != null) + { + var t = value.GetType(); + if (t == typeof(C)) + { + return (C)value; + } + if (t == typeof(int)) + { + return new C((int)value); + } + } + + return base.ConvertFrom(context, culture, value); + } + + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) + { + if (value is C wrappedValue) + { + if (destinationType == WrapperType) + { + return wrappedValue; + } + + if (destinationType == ValueType) + { + return wrappedValue.AsPrimitive(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + } +} diff --git a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs index bbb057c..de69d92 100644 --- a/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs +++ b/sandbox/Generated/UnitGenerator/UnitGenerator.SourceGenerator/UnitOfAttribute.cs @@ -3,8 +3,10 @@ // #pragma warning disable CS8669 #pragma warning disable CS8625 -#nullable enable using System; +#if NET7_0_OR_GREATER +using System.Numerics; +#endif namespace UnitGenerator { @@ -13,7 +15,7 @@ internal class UnitOfAttribute : Attribute { public Type Type { get; } public UnitGenerateOptions Options { get; } - public UnitArithmeticOperators ArithmeticOperators { get; set; } + public UnitArithmeticOperators ArithmeticOperators { get; set; } = UnitArithmeticOperators.All; public string ToStringFormat { get; set; } public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None) @@ -46,7 +48,7 @@ internal enum UnitGenerateOptions [Flags] internal enum UnitArithmeticOperators { - Number = 0, + All = Addition | Subtraction | Multiply | Division | Increment | Decrement, Addition = 1, Subtraction = 1 << 1, Multiply = 1 << 2, @@ -54,35 +56,4 @@ internal enum UnitArithmeticOperators Increment = 1 << 4, Decrement = 1 << 5, } - -#if NET7_0_OR_GREATER - internal static class AsNumber where T : INumber - { - public static T One => T.One; - public static int Radix => T.Radix; - public static T Zero => T.Zero; - public static T Abs(T value) => T.Abs(value); - public static bool IsCanonical(T value) => T.IsCanonical(value); - public static bool IsComplexNumber(T value) => T.IsComplexNumber(value); - public static bool IsEvenInteger(T value) => T.IsEvenInteger(value); - public static bool IsFinite(T value) => T.IsFinite(value); - public static bool IsImaginaryNumber(T value) => T.IsImaginaryNumber(value); - public static bool IsInfinity(T value) => T.IsInfinity(value); - public static bool IsInteger(T value) => T.IsInteger(value); - public static bool IsNaN(T value) => T.IsNaN(value); - public static bool IsNegative(T value) => T.IsNegative(value); - public static bool IsNegativeInfinity(T value) => T.IsNegativeInfinity(value); - public static bool IsNormal(T value) => T.IsNormal(value); - public static bool IsOddInteger(T value) => T.IsOddInteger(value); - public static bool IsPositive(T value) => T.IsPositive(value); - public static bool IsPositiveInfinity(T value) => T.IsPositiveInfinity(value); - public static bool IsRealNumber(T value) => T.IsRealNumber(value); - public static bool IsSubnormal(T value) => T.IsSubnormal(value); - public static bool IsZero(T value) => T.IsZero(value); - public static T MaxMagnitude(T x, T y) => T.MaxMagnitude(x, y); - public static T MaxMagnitudeNumber(T x, T y) => T.MaxMagnitudeNumber(x, y); - public static T MinMagnitude(T x, T y) => T.MinMagnitude(x, y); - public static T MinMagnitudeNumber(T x, T y) => T.MinMagnitudeNumber(x, y); - } -#endif } diff --git a/src/UnitGenerator/SourceGenerator.cs b/src/UnitGenerator/SourceGenerator.cs index 462bd51..1a4d7fd 100644 --- a/src/UnitGenerator/SourceGenerator.cs +++ b/src/UnitGenerator/SourceGenerator.cs @@ -33,7 +33,7 @@ public void Execute(GeneratorExecutionContext context) var model = context.Compilation.GetSemanticModel(type.SyntaxTree); // retrieve attribute parameter - var prop = new UnitOfAttributeProperty(); + var prop = new UnitOfAttributeProperty { ArithmeticOperators = UnitArithmeticOperators.All }; if (attr.ArgumentList is null) goto ADD; @@ -133,7 +133,7 @@ internal class UnitOfAttribute : Attribute { public Type Type { get; } public UnitGenerateOptions Options { get; } - public UnitArithmeticOperators ArithmeticOperators { get; set; } + public UnitArithmeticOperators ArithmeticOperators { get; set; } = UnitArithmeticOperators.All; public string ToStringFormat { get; set; } public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None) @@ -166,7 +166,7 @@ internal enum UnitGenerateOptions [Flags] internal enum UnitArithmeticOperators { - Number = 0, + All = Addition | Subtraction | Multiply | Division | Increment | Decrement, Addition = 1, Subtraction = 1 << 1, Multiply = 1 << 2, @@ -174,39 +174,6 @@ internal enum UnitArithmeticOperators Increment = 1 << 4, Decrement = 1 << 5, } - -#if NET7_0_OR_GREATER - internal static class AsNumber where T : INumber - { - public static T One => T.One; - public static int Radix => T.Radix; - public static T Zero => T.Zero; - public static T Abs(T value) => T.Abs(value); - public static T AdditiveIdentity => T.AdditiveIdentity; - public static T MultiplicativeIdentity => T.MultiplicativeIdentity; - public static bool IsCanonical(T value) => T.IsCanonical(value); - public static bool IsComplexNumber(T value) => T.IsComplexNumber(value); - public static bool IsEvenInteger(T value) => T.IsEvenInteger(value); - public static bool IsFinite(T value) => T.IsFinite(value); - public static bool IsImaginaryNumber(T value) => T.IsImaginaryNumber(value); - public static bool IsInfinity(T value) => T.IsInfinity(value); - public static bool IsInteger(T value) => T.IsInteger(value); - public static bool IsNaN(T value) => T.IsNaN(value); - public static bool IsNegative(T value) => T.IsNegative(value); - public static bool IsNegativeInfinity(T value) => T.IsNegativeInfinity(value); - public static bool IsNormal(T value) => T.IsNormal(value); - public static bool IsOddInteger(T value) => T.IsOddInteger(value); - public static bool IsPositive(T value) => T.IsPositive(value); - public static bool IsPositiveInfinity(T value) => T.IsPositiveInfinity(value); - public static bool IsRealNumber(T value) => T.IsRealNumber(value); - public static bool IsSubnormal(T value) => T.IsSubnormal(value); - public static bool IsZero(T value) => T.IsZero(value); - public static T MaxMagnitude(T x, T y) => T.MaxMagnitude(x, y); - public static T MaxMagnitudeNumber(T x, T y) => T.MaxMagnitudeNumber(x, y); - public static T MinMagnitude(T x, T y) => T.MinMagnitude(x, y); - public static T MinMagnitudeNumber(T x, T y) => T.MinMagnitudeNumber(x, y); - } -#endif } """; @@ -273,99 +240,70 @@ namespace {{ns}} sb.AppendLine($$""" [System.ComponentModel.TypeConverter(typeof({{unitTypeName}}TypeConverter))] - readonly partial struct {{unitTypeName}} + readonly partial struct {{unitTypeName}} + : IEquatable<{{unitTypeName}}> +#if NET7_0_OR_GREATER + , IEqualityOperators<{{unitTypeName}}, {{unitTypeName}}, bool> +#endif """); - if (prop.IsNumber()) + if (prop.HasFlag(UnitGenerateOptions.Comparable) && + !prop.HasFlag(UnitGenerateOptions.WithoutComparisonOperator)) { sb.AppendLine($$""" -#if NET7_0_OR_GREATER - : INumber<{{unitTypeName}}> -#else - : IEquatable<{{unitTypeName}}> , IComparable<{{unitTypeName}}> - , IComparable +#if NET7_0_OR_GREATER + , IComparisonOperators<{{unitTypeName}}, {{unitTypeName}}, bool> #endif """); } - else + if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) { - sb.AppendLine($$""" - : IEquatable<{{unitTypeName}}> -#if NET7_0_OR_GREATER - , IEqualityOperators<{{unitTypeName}}, {{unitTypeName}}, bool> -#endif -"""); - if (prop.HasFlag(UnitGenerateOptions.Comparable)) + sb.AppendLine("#if NET7_0_OR_GREATER"); + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition)) { sb.AppendLine($$""" - , IComparable<{{unitTypeName}}> -"""); - if (!prop.HasFlag(UnitGenerateOptions.WithoutComparisonOperator)) - { - sb.AppendLine($$""" -#if NET7_0_OR_GREATER - , IComparisonOperators<{{unitTypeName}}, {{unitTypeName}}, bool> -#endif + , IAdditionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); - } } - if (prop.HasFlag(UnitGenerateOptions.ArithmeticOperator)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) { - sb.AppendLine("#if NET7_0_OR_GREATER"); - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition)) - { - sb.AppendLine($$""" - , IAdditionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> -"""); - } - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) - { - sb.AppendLine($$""" + sb.AppendLine($$""" , ISubtractionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); - } - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition) || - prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) - { - sb.AppendLine($$""" - , IAdditiveIdentity<{{unitTypeName}}, {{unitTypeName}}> -"""); - } - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply)) - { - sb.AppendLine($$""" + } + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply)) + { + sb.AppendLine($$""" , IMultiplyOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); - } - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) - { - sb.AppendLine($$""" + } + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) + { + sb.AppendLine($$""" , IDivisionOperators<{{unitTypeName}}, {{unitTypeName}}, {{unitTypeName}}> """); - } - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply) || - prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) - { - sb.AppendLine($$""" - , IMultiplicativeIdentity<{{unitTypeName}}, {{unitTypeName}}> + } + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply) || + prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) + { + sb.AppendLine($$""" , IUnaryPlusOperators<{{unitTypeName}}, {{unitTypeName}}> , IUnaryNegationOperators<{{unitTypeName}}, {{unitTypeName}}> """); - } - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Increment)) - { - sb.AppendLine($$""" + } + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Increment)) + { + sb.AppendLine($$""" , IIncrementOperators<{{unitTypeName}}> """); - } - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Decrement)) - { - sb.AppendLine($$""" + } + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Decrement)) + { + sb.AppendLine($$""" , IDecrementOperators<{{unitTypeName}}> """); - } - sb.AppendLine("#endif"); } + sb.AppendLine("#endif"); } sb.AppendLine($$""" @@ -619,18 +557,9 @@ public static bool TryParse(string s, out {{unitTypeName}} result) // UnitGenerateOptions.ArithmeticOperator """); - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition) || - prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition)) { - sb.AppendLine($$""" -#if NET7_0_OR_GREATER - public static {{unitTypeName}} AdditiveIdentity => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.AdditiveIdentity); -#endif - -"""); - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Addition)) - { - sb.AppendLine($$""" + sb.AppendLine($$""" public static {{unitTypeName}} operator +({{unitTypeName}} x, {{unitTypeName}} y) { checked @@ -640,10 +569,10 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } """); - } - if (prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) - { - sb.AppendLine($$""" + } + if (prop.HasArithmeticOperator(UnitArithmeticOperators.Subtraction)) + { + sb.AppendLine($$""" public static {{unitTypeName}} operator -({{unitTypeName}} x, {{unitTypeName}} y) { checked @@ -653,16 +582,12 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } """); - } - } // End Addition, Subtraction + } if (prop.HasArithmeticOperator(UnitArithmeticOperators.Multiply) || prop.HasArithmeticOperator(UnitArithmeticOperators.Division)) { sb.AppendLine($$""" -#if NET7_0_OR_GREATER - public static {{unitTypeName}} MultiplicativeIdentity => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MultiplicativeIdentity); -#endif public static {{unitTypeName}} operator +({{unitTypeName}} value) => new(({{innerTypeName}})(+value.value)); public static {{unitTypeName}} operator -({{unitTypeName}} value) => new(({{innerTypeName}})(-value.value)); @@ -785,7 +710,7 @@ public static bool TryParse(string s, out {{unitTypeName}} result) } } // End ValueArithmeticOperator - if (prop.IsNumber() || prop.HasFlag(UnitGenerateOptions.Comparable)) + if (prop.HasFlag(UnitGenerateOptions.Comparable)) { sb.AppendLine($$""" // UnitGenerateOptions.Comparable @@ -794,24 +719,9 @@ public int CompareTo({{unitTypeName}} other) { return value.CompareTo(other.value); } - - public int CompareTo(object? obj) - { - if (obj == null) - { - return 1; - } - - if (obj is {{unitTypeName}} other) - { - return value.CompareTo(other.value); - } - throw new ArgumentException(); - } """); } - if (prop.IsNumber() || - (prop.HasFlag(UnitGenerateOptions.Comparable) && !prop.HasFlag(UnitGenerateOptions.WithoutComparisonOperator))) + if (prop.HasFlag(UnitGenerateOptions.Comparable) && !prop.HasFlag(UnitGenerateOptions.WithoutComparisonOperator)) { sb.AppendLine($$""" public static bool operator >({{unitTypeName}} x, {{unitTypeName}} y) @@ -837,148 +747,6 @@ public int CompareTo(object? obj) """); } - if (prop.IsNumber()) - { - sb.AppendLine($$""" - public static {{unitTypeName}} operator %({{unitTypeName}} x, {{unitTypeName}} y) => new {{unitTypeName}}(({{innerTypeName}})(x.value % y.value)); - - // IFormattable - - public string ToString(string? format, IFormatProvider? formatProvider) => value.ToString(format, formatProvider); - -#if NET6_0_OR_GREATER - // ISpanFormattable - - public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) - { - return value.TryFormat(destination, out charsWritten, format, provider); - } -#endif -#if NET7_0_OR_GREATER - // IParsable - - public static {{unitTypeName}} Parse(string s, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, provider)); - - public static bool TryParse(string? s, IFormatProvider? provider, out {{unitTypeName}} result) - { - if ({{innerTypeName}}.TryParse(s, provider, out var parsedValue)) - { - result = new {{unitTypeName}}(parsedValue); - return true; - } - result = default; - return false; - } - - // ISpanParsable - - public static {{unitTypeName}} Parse(ReadOnlySpan s, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, provider)); - - public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out {{unitTypeName}} result) - { - if ({{innerTypeName}}.TryParse(s, provider, out var parsedValue)) - { - result = new {{unitTypeName}}(parsedValue); - return true; - } - result = default; - return false; - } - - // INumberBase - - public static {{unitTypeName}} One => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.One); - public static int Radix => global::UnitGenerator.AsNumber<{{innerTypeName}}>.Radix; - public static {{unitTypeName}} Zero => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.Zero); - public static {{unitTypeName}} Abs({{unitTypeName}} value) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.Abs(value.value)); - public static bool IsCanonical({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsCanonical(value.value); - public static bool IsComplexNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsComplexNumber(value.value); - public static bool IsEvenInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsEvenInteger(value.value); - public static bool IsFinite({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsFinite(value.value); - public static bool IsImaginaryNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsImaginaryNumber(value.value); - public static bool IsInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsInfinity(value.value); - public static bool IsInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsInteger(value.value); - public static bool IsNaN({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsNaN(value.value); - public static bool IsNegative({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsNegative(value.value); - public static bool IsNegativeInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsNegativeInfinity(value.value); - public static bool IsNormal({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsNormal(value.value); - public static bool IsOddInteger({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsOddInteger(value.value); - public static bool IsPositive({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsPositive(value.value); - public static bool IsPositiveInfinity({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsPositiveInfinity(value.value); - public static bool IsRealNumber({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsRealNumber(value.value); - public static bool IsSubnormal({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsSubnormal(value.value); - public static bool IsZero({{unitTypeName}} value) => global::UnitGenerator.AsNumber<{{innerTypeName}}>.IsZero(value.value); - public static {{unitTypeName}} MaxMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MaxMagnitude(x.value, y.value)); - public static {{unitTypeName}} MaxMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MaxMagnitudeNumber(x.value, y.value)); - public static {{unitTypeName}} MinMagnitude({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MinMagnitude(x.value, y.value)); - public static {{unitTypeName}} MinMagnitudeNumber({{unitTypeName}} x, {{unitTypeName}} y) => new(global::UnitGenerator.AsNumber<{{innerTypeName}}>.MinMagnitudeNumber(x.value, y.value)); - - public static bool TryConvertFromChecked(TOther value, out {{unitTypeName}} result) where TOther : INumberBase - { - result = default; - return false; - } - - public static bool TryConvertFromSaturating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase - { - result = default; - return false; - } - - public static bool TryConvertFromTruncating(TOther value, out {{unitTypeName}} result) where TOther : INumberBase - { - result = default; - return false; - - } - - public static bool TryConvertToChecked({{unitTypeName}} value, out TOther result) where TOther : INumberBase - { - result = default; - return false; - } - - public static bool TryConvertToSaturating({{unitTypeName}} value, out TOther result) where TOther : INumberBase - { - result = default; - return false; - } - - public static bool TryConvertToTruncating({{unitTypeName}} value, out TOther result) where TOther : INumberBase - { - result = default; - return false; - } - - public static {{unitTypeName}} Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); - public static {{unitTypeName}} Parse(string s, NumberStyles style, IFormatProvider? provider) => new {{unitTypeName}}({{innerTypeName}}.Parse(s, style, provider)); - - public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider, out {{unitTypeName}} result) - { - if ({{innerTypeName}}.TryParse(s, style, provider, out var value)) - { - result = new {{unitTypeName}}(value); - return true; - } - result = default; - return false; - } - - public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out {{unitTypeName}} result) - { - if ({{innerTypeName}}.TryParse(s, style, provider, out var value)) - { - result = new {{unitTypeName}}(value); - return true; - } - result = default; - return false; - } -#endif - -"""); - } // End Number - if (prop.HasFlag(UnitGenerateOptions.JsonConverter)) { sb.AppendLine($$""" @@ -1260,21 +1028,14 @@ struct UnitOfAttributeProperty public bool HasFlag(UnitGenerateOptions options) => Options.HasFlag(options); - public bool IsNumber() => HasFlag(UnitGenerateOptions.ArithmeticOperator) && - ArithmeticOperators == UnitArithmeticOperators.Number; - public bool HasArithmeticOperator(UnitArithmeticOperators op) { - return HasFlag(UnitGenerateOptions.ArithmeticOperator) && - (ArithmeticOperators == UnitArithmeticOperators.Number || - ArithmeticOperators.HasFlag(op)); + return HasFlag(UnitGenerateOptions.ArithmeticOperator) && ArithmeticOperators.HasFlag(op); } public bool HasValueArithmeticOperator(UnitArithmeticOperators op) { - return HasFlag(UnitGenerateOptions.ValueArithmeticOperator) && - (ArithmeticOperators == UnitArithmeticOperators.Number || - ArithmeticOperators.HasFlag(op)); + return HasFlag(UnitGenerateOptions.ValueArithmeticOperator) && ArithmeticOperators.HasFlag(op); } public DbType GetDbType() diff --git a/src/UnitGenerator/UnitGenerateOptions.cs b/src/UnitGenerator/UnitGenerateOptions.cs index c166695..0051a7f 100644 --- a/src/UnitGenerator/UnitGenerateOptions.cs +++ b/src/UnitGenerator/UnitGenerateOptions.cs @@ -26,7 +26,7 @@ internal enum UnitGenerateOptions [Flags] internal enum UnitArithmeticOperators { - Number = 0, + All = Addition | Subtraction | Multiply | Division | Increment | Decrement, Addition = 1, Subtraction = 1 << 1, Multiply = 1 << 2, From 4670481c4a481866e6127b6d444d035b5a56b1bf Mon Sep 17 00:00:00 2001 From: hadashiA Date: Thu, 17 Aug 2023 17:18:06 +0900 Subject: [PATCH 12/12] Update README --- README.md | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index c38bedf..0dab20d 100644 --- a/README.md +++ b/README.md @@ -61,13 +61,24 @@ public readonly partial struct Hp { } [System.ComponentModel.TypeConverter(typeof(HpTypeConverter))] public readonly partial struct Hp + : IEquatable #if NET7_0_OR_GREATER - : INumber -#else - : IEquatable - , IComparable - , IComparable + , IEqualityOperators +#endif + , IComparable +#if NET7_0_OR_GREATER + , IComparisonOperators #endif +#if NET7_0_OR_GREATER + , IAdditionOperators + , ISubtractionOperators + , IMultiplyOperators + , IDivisionOperators + , IUnaryPlusOperators + , IUnaryNegationOperators + , IIncrementOperators + , IDecrementOperators +#endif { readonly int value; @@ -96,17 +107,6 @@ public readonly partial struct Hp public static Hp operator --(Hp x) => new Hp(checked((int)(x.value - 1))); public static Hp operator +(A value) => new((int)(+value.value)); public static Hp operator -(A value) => new((int)(-value.value)); - - // The .ArithmeticOperator option also generates all members of `System.Numerics.INumber` by default. -#if NET7_0_OR_GREATER - public static Hp AdditiveIdentity => new(global::UnitGenerator.AsNumber.AdditiveIdentity); - public static Hp MultiplicativeIdentity => new(global::UnitGenerator.AsNumber.MultiplicativeIdentity); - public static HP One => new(global::UnitGenerator.AsNumber.One); - public static int Radix => global::UnitGenerator.AsNumber.Radix; - public static Hp Zero => new(global::UnitGenerator.AsNumber.Zero); - public static Hp Abs(Hp value) => new(global::UnitGenerator.AsNumber.Abs(value.value)); - // etc...... -#endif // UnitGenerateOptions.ValueArithmeticOperator public static Hp operator +(Hp x, in int y) => new Hp(checked((int)(x.value + y))); @@ -371,14 +371,13 @@ public readonly partial struct Hp { } | Value | Generates | |-------------------------------------|----------------------------------------------------------------------------------------| -| UnitArithmeticOperators.Addition | `T operator +(T, T)`, `T AdditiveIdentity` | -| UnitArithmeticOperators.Subtraction | `T operator -(T, T)`, `T AdditiveIdentity` | -| UnitArithmeticOperators.Multiply | `T operator *(T, T)`, `T operator +(T)`, `T operator-(T)`, `T MultiplicativeIdentity` | -| UnitArithmeticOperators.Division | `T operator /(T, T)`, `T operator +(T)`, `T operator-(T)`, `T MultiplicativeIdentity` | +| UnitArithmeticOperators.Addition | `T operator +(T, T)` | +| UnitArithmeticOperators.Subtraction | `T operator -(T, T)` | +| UnitArithmeticOperators.Multiply | `T operator *(T, T)`, `T operator +(T)`, `T operator-(T)` | +| UnitArithmeticOperators.Division | `T operator /(T, T)`, `T operator +(T)`, `T operator-(T)` | | UnitArithmeticOperators.Increment | `T operator ++(T)` | | UnitArithmeticOperators.Decrement | `T operator --(T)` | - ### ValueArithmeticOperator ```csharp