Skip to content

Commit

Permalink
Merge pull request #9 from hikarin522/develop
Browse files Browse the repository at this point in the history
v0.5.0
  • Loading branch information
hikarin522 authored Dec 5, 2022
2 parents e2113be + e731752 commit ff415a4
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 46 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>

<Version>0.4.0</Version>
<Version>0.5.0</Version>
<Authors>hikarin522</Authors>
<Copyright>(c) 2022 hikarin522.</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
21 changes: 8 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,22 @@ readonly partial struct SampleVariant: IEquatable<SampleVariant>
public readonly partial struct SampleVariant1 : IValueVariant<SampleVariant1, int, Guid, DateTime>
{
public static explicit operator SampleVariant1(SampleVariant2 value)
=> value.TryCast(out var result) ? result : throw new InvalidCastException();
=> value.Accept(SampleVariant2Converter.Instance);

public readonly bool TryCast(out SampleVariant2 result)
private sealed class SampleVariant2Converter : DefaultConverter<SampleVariant2Converter>, SampleVariant2.IFuncVisitor<SampleVariant1>
{
if (this == default) { result = default; return true; }
this.Accept(SampleVariant2.DefaultConverter.Instance, out result);
return result != default;
public SampleVariant1 Visit(in long value) => throw new InvalidCastException();
public SampleVariant1 Visit(in bool value) => throw new InvalidCastException();
}
}

[ValueVariant]
public readonly partial struct SampleVariant2 : IValueVariant<SampleVariant2, Guid, DateTime, int, long, bool>
{
public static explicit operator SampleVariant2(SampleVariant1 value)
=> value.TryCast(out var result) ? result : throw new InvalidCastException();
// implicit because SampleVariant1 ⊂ SampleVariant2
public static implicit operator SampleVariant2(SampleVariant1 value)
=> value.Accept(SampleVariant1Converter.Instance);

public readonly bool TryCast(out SampleVariant1 result)
{
if (this == default) { result = default; return true; }
this.Accept(SampleVariant1.DefaultConverter<long, bool>.Instance, out result);
return result != default;
}
private sealed class SampleVariant1Converter : DefaultConverter<SampleVariant1Converter>, SampleVariant1.IFuncVisitor<SampleVariant2> { }
}
```
23 changes: 4 additions & 19 deletions ValueVariant.Generator/ValueVariantTemplate.tt
Original file line number Diff line number Diff line change
Expand Up @@ -155,32 +155,17 @@ namespace <#= Namespace #>
public TR Accept<TA1, TR>(V2.IValueVariantGenericFuncVisitor<TA1, TR> visitor, TA1 arg1)
=> V2.Details.ValueVariant<<#= Join(1, Count, e => $"T{e}") #>>.AcceptGenericFuncVisitor<T, V2.IValueVariantGenericFuncVisitor<TA1, TR>, TA1, TR>(this, visitor, arg1);

public class DefaultConverter : IFuncVisitor<T>
public abstract class DefaultConverter<TConverter> : IFuncVisitor<T>
where TConverter : DefaultConverter<TConverter>, new()
{
public static DefaultConverter Instance { get; } = new DefaultConverter();
public static TConverter Instance { get; } = new TConverter();

<# for (var i = 1; i <= Count; ++i ) { #>
public T Visit(in T<#= i #> value) => value;
<# } #>
}

public class DefaultConverter<TEx1> : DefaultConverter, V2.IValueVariantFuncVisitor<TEx1, T>
where TEx1 : unmanaged
{
public static new DefaultConverter<TEx1> Instance { get; } = new DefaultConverter<TEx1>();

public T Visit(in TEx1 value) => default;
}
<# for (var i = 2; i <= 4; ++i ) { #>

public class DefaultConverter<<#= Join(1, i, e => $"TEx{e}") #>> : DefaultConverter<<#= Join(1, i - 1, e => $"TEx{e}") #>>, V2.IValueVariantFuncVisitor<TEx<#= i #>, T>
<#= string.Join(" ", Range(1, i, e => $"where TEx{e}: unmanaged")) #>
{
public static new DefaultConverter<<#= Join(1, i, e => $"TEx{e}") #>> Instance { get; } = new DefaultConverter<<#= Join(1, i, e => $"TEx{e}") #>>();

public T Visit(in TEx<#= i #> value) => default;
}
<# } #>
public sealed class DefaultConverter : DefaultConverter<DefaultConverter> { }
<# if (Options.HasFlag(ValueVariantGenerateOptions.MessagePackFormatter)) { #>

private sealed class MessagePackFormatter : IMessagePackFormatter<T>
Expand Down
21 changes: 8 additions & 13 deletions ValueVariant.Test/TestVariant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ namespace ValueVariant.Test;
public readonly partial struct TestVariant : IValueVariant<TestVariant, int, TestStruct<Guid>, DateTime>
{
public static explicit operator TestVariant(TestVariant2 value)
=> value.TryCast(out var result) ? result : throw new InvalidCastException();
=> value.Accept(TestVariant2Converter.Instance);

public readonly bool TryCast(out TestVariant2 result)
private sealed class TestVariant2Converter : DefaultConverter<TestVariant2Converter>, TestVariant2.IFuncVisitor<TestVariant>
{
if (this == default) { result = default; return true; }
this.Accept(TestVariant2.DefaultConverter.Instance, out result);
return result != default;
public TestVariant Visit(in long value) => throw new InvalidCastException();
public TestVariant Visit(in bool value) => throw new InvalidCastException();
}
}

Expand All @@ -34,13 +33,9 @@ public readonly bool TryCast(out TestVariant2 result)
[ValueVariant]
public readonly partial struct TestVariant2 : IValueVariant<TestVariant2, TestStruct<Guid>, DateTime, int, long, bool>
{
public static explicit operator TestVariant2(TestVariant value)
=> value.TryCast(out var result) ? result : throw new InvalidCastException();
// implicit because TestVariant ⊂ TestVariant2
public static implicit operator TestVariant2(TestVariant value)
=> value.Accept(TestVariantConverter.Instance);

public readonly bool TryCast(out TestVariant result)
{
if (this == default) { result = default; return true; }
this.Accept(TestVariant.DefaultConverter<long, bool>.Instance, out result);
return result != default;
}
private sealed class TestVariantConverter : DefaultConverter<TestVariantConverter>, TestVariant.IFuncVisitor<TestVariant2> { }
}

0 comments on commit ff415a4

Please sign in to comment.