Skip to content

Commit

Permalink
Merge pull request #30 from Cysharp/hadashiA/numeric
Browse files Browse the repository at this point in the history
Add options to define arithmetic operators separately
  • Loading branch information
hadashiA committed Aug 17, 2023
2 parents 3deabf1 + 4670481 commit 41a364b
Show file tree
Hide file tree
Showing 14 changed files with 707 additions and 133 deletions.
88 changes: 69 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,25 @@ public readonly partial struct Hp { }
// -- generates
[System.ComponentModel.TypeConverter(typeof(HpTypeConverter))]
public readonly partial struct Hp : IEquatable<Hp> , IComparable<Hp>
public readonly partial struct Hp
: IEquatable<Hp>
#if NET7_0_OR_GREATER
, IEqualityOperators<Hp, Hp, bool>
#endif
, IComparable<Hp>
#if NET7_0_OR_GREATER
, IComparisonOperators<Hp, Hp, bool>
#endif
#if NET7_0_OR_GREATER
, IAdditionOperators<Hp, Hp, Hp>
, ISubtractionOperators<Hp, Hp, Hp>
, IMultiplyOperators<Hp, Hp, Hp>
, IDivisionOperators<Hp, Hp, Hp>
, IUnaryPlusOperators<Hp, Hp>
, IUnaryNegationOperators<Hp, Hp>
, IIncrementOperators<Hp>
, IDecrementOperators<Hp>
#endif
{
readonly int value;

Expand All @@ -81,25 +99,27 @@ public readonly partial struct Hp : IEquatable<Hp> , IComparable<Hp>
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));

// 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));
Expand Down Expand Up @@ -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) { ... }
}
}
```
Expand Down Expand Up @@ -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. 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}`.

## UnitGenerateOptions

Expand Down Expand Up @@ -324,13 +351,36 @@ 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<T>](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)` |
| 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
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)));
Expand Down
2 changes: 2 additions & 0 deletions sandbox/ConsoleApp/AllPrimitives.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
2 changes: 1 addition & 1 deletion sandbox/ConsoleApp/ConsoleApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
37 changes: 37 additions & 0 deletions sandbox/ConsoleApp/Operators.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using UnitGenerator;

namespace ConsoleApp
{
namespace ConsoleApp
{
[UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Addition)]
public readonly partial struct Add
{
}

[UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Subtraction)]
public readonly partial struct Sub
{
}

[UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Multiply)]
public readonly partial struct Mul
{
}

[UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Division)]
public readonly partial struct Div
{
}

[UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Increment)]
public readonly partial struct Inc
{
}

[UnitOf(typeof(int), UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator, ArithmeticOperators = UnitArithmeticOperators.Decrement)]
public readonly partial struct Dec
{
}
}
}
5 changes: 2 additions & 3 deletions sandbox/ConsoleApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@

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)));
Expand Down Expand Up @@ -83,7 +82,7 @@ public void Foo()
_ = AsPrimitive();
}
}

[UnitOf(typeof(string), UnitGenerateOptions.ParseMethod)]
public readonly partial struct StringId { }
}
Expand Down
2 changes: 1 addition & 1 deletion sandbox/FileGenerate/FileGenerate.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>

<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(ProjectDir)..\Generated</CompilerGeneratedFilesOutputPath>
Expand Down
12 changes: 6 additions & 6 deletions sandbox/FileGenerate/SimplePrimitive.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -16,4 +11,9 @@ namespace FileGenerate
public readonly partial struct B
{
}

[UnitOf(typeof(int), UnitGenerateOptions.Comparable | UnitGenerateOptions.ArithmeticOperator | UnitGenerateOptions.ValueArithmeticOperator)]
public readonly partial struct C
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@
// </auto-generated>
#pragma warning disable CS8669
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<A>
#if NET7_0_OR_GREATER
, IEqualityOperators<A, A, bool>
#endif
{
readonly int value;

Expand Down Expand Up @@ -47,28 +55,29 @@ 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

private class ATypeConverter : System.ComponentModel.TypeConverter
{
private static readonly Type WrapperType = typeof(A);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@
// </auto-generated>
#pragma warning disable CS8669
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<B>
#if NET7_0_OR_GREATER
, IEqualityOperators<B, B, bool>
#endif
{
readonly string value;

Expand Down Expand Up @@ -47,28 +55,29 @@ 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

private class BTypeConverter : System.ComponentModel.TypeConverter
{
private static readonly Type WrapperType = typeof(B);
Expand Down

0 comments on commit 41a364b

Please sign in to comment.